GUI element update strategies in App Designer
10 views (last 30 days)
Long term Matlab user here but building my first GUI apps with App Designer.
I am struggling with the strategy to update the UIcontrols.
In the tutorial examples, UIcontrols are updated whenever and wherever needed. However, these are very simple examples.
In my GUI, I have UIcontrols which interact closely, eg disabling/enabling elements in case of valid/invalid input of another UIcontrol, updating the value, updating a statusbar, etc which is more complex than the basic examples.
If I would do the UIcontrol updates as in these examples (mostly within the callbacks), a lot of code would be repeated and I would loose oversight and ease of maintenance.
So what I do now is whenever I need an update of the UIcontrols:
- Set a boolean for each UIcontrol (eg app.StatusCode = true) which might need an update after running the callback
- Call a function app.updateUIcontrols() at the end of the running function
function EditFieldCalculateValueChangedFcn(app, event)
val = event.Value;
if val > 0
app.StatusCodeValue = 'Good';
app.StatusCodeValue = 'Bad';
app.StatusCode = true;
% set boolean value of other UIcontrols to update
The function updateUIcontrols() checks all UIcontrols and performs an update if needed.
if app.StatusCode = true
app.EditFieldStatusCode.Value = app.StatusCodeValue;
app.StatusCode = false;
This has also some drawbacks
- A lot of extra variables are needed (a boolean and eventually a value variable for each UIcontrol)
- A lot of unnecessary checking (if I have 50 UIcontrols and only need 1 to be update, it will still check the others too)
- The UIcontrols are updated sequentially so I must make sure that an update of one UIcontrol does not influence the state of an UIcontrol checked earlier
- The UIcontrols are only updated at discrete timepoints, not necessarily immediately
- Fill in yourself ;-)
Are there any strategies to tackle this problem?
Are there examples of good GUI coding practices in Matlab?
Mario Malic on 12 Oct 2021
Edited: Mario Malic on 19 Oct 2021
I did recently, something similar. You can create and use the same callback for multiple components. If you can group up your components that interact with each other either by some logic it would make it easier. Let's say you have multiple different components that operate (and interact with each other) in one tab, then the same group of components in the other tab etc. - this could be good example of grouping up.
Then, you would "collect" this group of components in array for graphic objects gobjects, and assign the same callback to each component. So, once you enter into callback, you first identify which object has fired the event and according to it, execute some code.
This code would be an idea of what I meant. I hope it's clear enough, even though I am afraid it may not be.
properties(Access = public)
groupObjs = gobjects(10, 1); % assign objects to array
groupBool = false(10,1);
% some callback gets executed
function callback(source, event)
objIdx = find(source == app.groupObjs); % get index in the groupObjs, isequal might also work
app.groupBool(objIdx) = true;
% call a function that updates component based on groupBool property
Edit 1: I have made an example, so you can check the idea. I do not know whether this is the best way to do things, I am up for some brainstorming.
Read first the interactions on the GUI, then see how things are implemented. In the code, there is some text regarding the boolean array and function that only updates particular components.
This example would be useful if we would have multiple tabs with same/similar components. Apologies if I haven't made myself clear (which, unfortunately, might be true).
Reshma Nerella on 3 Feb 2022
Instead of having many unnecessary boolean variables or many callbacks with similar code, you can add a single callback to multiple app designer components.
Refer to the following documentation page to know more in detail: https://www.mathworks.com/help/matlab/creating_guis/share-callbacks-between-components-in-app-designer.html#d123e6200