I'm trying to find all checkboxes in a specific panel that are checked, get their tags/names and perform different actions depending on how many of them are checked.
I tried it like this but the cell array remains empty (cell array in question is "selected_names"):
cla(app.axFeatures);
% Find all the checkbox objects belonging to features
checkboxes = findall(app.features,'type','uicheckbox');
% Initialize an empty cell array to store the names of the selected checkboxes
selected_names = {};
% Loop through the checkboxes and check which ones are selected
for i=1:numel(checkboxes)
if get(checkboxes(i), 'Value') == 1
% If the checkbox is selected, add its name to the cell array
selected_names{end+1} = get(checkboxes(i), 'Tag');
end
end
if numel(selected_names) == 3
app.analyzer.histograms_3D(selected_names{1}, selected_names{2}, selected_names{3}, app.axFeatures);
elseif numel(selected_names) == 2
app.analyzer.histograms_gaussians(selected_names{1}, selected_names{2}, app.axFeatures);
elseif numel(selected_names) == 1
app.analyzer.histogram(selected_names{1}, app.axFeatures)
else
% Display error prompt for no selected checkboxes or more than 3
errordlg("Please select between 1 and 3 checkboxes.", "Invalid Selection");
end
end
How do I fix this?

7 Kommentare

Chris
Chris am 28 Jan. 2023
Have you assigned tags to your checkboxes?
Kevin Gjoni
Kevin Gjoni am 28 Jan. 2023
yes
Because unless your app sets it, the 'Tag' property is empty...see the doc for 'CheckBox Properties' that says for the Tag property--
Tag — Object identifier
'' (default) | character vector | string scalar
Object identifier, specified as a character vector or string scalar. You can specify
a unique Tag value to serve as an identifier for an object. When you need access to
the object elsewhere in your code, you can use the findobj function to search for the
object based on the Tag value.
BUT, in order to do that, the property value has to be set to begin with. If you just want an identifier for each, then set the property in the design mode.
i set the tag in the design mode. When i set a breakpoint after the for iteration and run the code snippets in command window while the app is running, for example
>> selected_names{end+1} = get(checkboxes(1), 'Tag');
it works and my array gets filled with the tag from the first checkbox. But it doesn't work in the app...
checkboxes = findall(app.features,'type','uicheckbox');
is that returning a nonempty result?
Kevin Gjoni
Kevin Gjoni am 28 Jan. 2023
yes, this returns the checkboxes in my specified panel
What shows up for
[checkboxes.Value]
? in particular are there any nonzero values?
Does the code contain any pause() or uiwait() or waitfor() or drawnow() between the point at which the user clicks and the time this function executes?

Melden Sie sich an, um zu kommentieren.

 Akzeptierte Antwort

dpb
dpb am 28 Jan. 2023
Verschoben: dpb am 28 Jan. 2023

0 Stimmen

We can't debug what we don't have, which is a sample app that recreates the problem...looks like all should work just fine here although it can be made more efficient...
fig = uifigure;
pnl = uipanel(fig);
hcbx = uicheckbox(pnl);
hcbx(2)=uicheckbox(pnl);
hcbx(2).Position=hcbx(1).Position+[0 -30 0 0];
set(hcbx,{'Tag'},cellstr("CBox"+[1:2].'))
hcbx(2).Value=true;
% now query them...
names=get(hcbx,'Tag'); % the assigned tag values
state=cell2mat(get(hcbx,'Value')); % array of state values (logicals)
selected_names=names(state) % and the checked ones only
produces
>>
...above code...
selected_names =
1×1 cell array
{'CBox2'}
>>
here. I didn't wrap it inside an app, but the logic seems sound; something must be going wrong elsewhere that the Tag values are getting trashed.

5 Kommentare

I attached the app. The code in question is in "function btnDrawButtonPushed(app, event)".
As I said in an earlier comment, when i set a breakpoint after the for iteration the array remains empty but when run the code snippets in command window while the app is running with the breakpoint still there, for example
>> selected_names{end+1} = get(checkboxes(1), 'Tag');
it works and my array gets filled with the tag from the first checkbox. But it doesn't work in the app...
dpb
dpb am 28 Jan. 2023
Bearbeitet: dpb am 28 Jan. 2023
I commented out the image stuff in the startup and replaced your code in the Draw callback with my suggested code snippet above and seemed to work just fine...the disp() call I added to echo the selected_names variable to the command window produced
Unrecognized method, property, or field 'oMalignantDataset' for class 'GUI_FINAL'.
Error in GUI_FINAL/startupFcn (line 52)
app.spnMalignantImageset.Limits = [1 app.oMalignantDataset.size];
Error in GUI_FINAL (line 382)
runStartupFcn(app, @startupFcn)
141 selected_names=names(state);
{'Entropy'}
Unrecognized method, property, or field 'analyzer' for class 'GUI_FINAL'.
Error in GUI_FINAL/btnDrawButtonPushed (line 148)
app.analyzer.histogram(selected_names{1}, app.axFeatures)
Error using matlab.ui.control.internal.controller.ComponentController/executeUserCallback (line 386)
Error while evaluating Button PrivateButtonPushedFcn.
{'Eccentricity'}
{'Entropy' }
Unrecognized method, property, or field 'analyzer' for class 'GUI_FINAL'.
Error in GUI_FINAL/btnDrawButtonPushed (line 146)
app.analyzer.histograms_gaussians(selected_names{1}, selected_names{2}, app.axFeatures);
Error using matlab.ui.control.internal.controller.ComponentController/executeUserCallback (line 386)
Error while evaluating Button PrivateButtonPushedFcn
The two sets of names did coincide with those I checked before "Draw"
Those were done without the debugger running so it doesn't have anything to do with being in debug mode or not...
I attached the modified code; you'll see the disp function in the callback function and the commented-out lines are still in the startup you'll need to put back in...
The actual code itself in replacement of your loop construct is
...
% Find all the checkbox objects belonging to features
checkboxes = findall(app.features,'type','uicheckbox');
names=get(checkboxes,'Tag'); % the list of tags; could be app global on startpu
state=cell2mat(get(checkboxes,'Value')); % the logical vector of which checked
selected_names=names(state); % save the checked tag values
disp(selected_names) % prove what we got w/o debugging...remove when done debugging of course
....
I didn't look past this point to see about further possible streamlining...although I'd venture to guess the state vector of which alternatives user checked would find great use in subsequent logic to do whatever it is that is done based on those.
Kevin Gjoni
Kevin Gjoni am 28 Jan. 2023
This works!!! Thank you for your time, you cant imagine how much this helps me!!
No problem, although if had taken suggested code at face value to begin with... :)
NOTA BENE:
checkboxes = findall(app.features,'type','uicheckbox');
names=get(checkboxes,'Tag');
Both of these could/should be determined as part of the startup code and held as global parameters for the application; there's no sense in searching for the same thing every time when it is fixed application data.
Kevin Gjoni
Kevin Gjoni am 28 Jan. 2023
will fix now, thank you

Melden Sie sich an, um zu kommentieren.

Weitere Antworten (0)

Kategorien

Mehr zu Startup and Shutdown finden Sie in Hilfe-Center und File Exchange

Produkte

Version

R2022a

Gefragt:

am 28 Jan. 2023

Kommentiert:

am 28 Jan. 2023

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by