Shika93
Shika93

Reputation: 659

Set values of multiple checkboxes in MATLAB

I have a popup window with 14 checkboxes (I click a button in my GUI, this other window with checkboxes opens, I check the ones I need and I close it) and I want to set their values if they have been already checked.

I used 14 global variables for the values of my checkboxes and I used this solution to set their value (in this way, when I reopen the window I see which checkbox is selected)

function figure_checkboxes_OpeningFcn(hObject, eventdata, handles, varargin)
handles.output = hObject;
guidata(hObject, handles);

global checkbox1
global checkbox2 %...to 14

if checkbox1 == 1
    set(handles.checkbox1,'Value',1);
end
if checkbox2 == 1
    set(handles.checkbox2,'Value',1);
end
% 14 if statement for each checkbox

Obviously when I define global checkbox1 is because I have a button that gets each checkboxe's value (i.e. checkbox1 = get(handles.checkbox1,'Value');)

Is there a more clever and compact way to avoid fourteen if statements?

Upvotes: 1

Views: 857

Answers (2)

Wolfie
Wolfie

Reputation: 30047

Please note up front, I discourage the use of global variables. However, without more detail of your code I'll work with what you've given...

You can use a single struct variable, store all the checkbox values in there and update in a loop:

function figure_checkboxes_OpeningFcn(hObject, eventdata, handles, varargin)
handles.output = hObject;
guidata(hObject, handles);

global checkboxValues % Struct with fields 'checkbox1', 'checkbox2', ...

% Loop using dynamic struct field name notation struct.('field')
for icb = 1:14
    cbName = sprintf( 'checkbox%.0f', icb );
    if checkboxValues.(cbName) == 1
        set( handles.(cbName), 'Value', 1 );
    end
end

You can make this look more streamlined using arrayfun, for basically the same operation. Replace the loop with this:

str = @(icb) sprintf('checkbox%.0f',icb);
arrayfun( @(icb) set( handles.(str(icb)), 'Value', checkboxValues.(str(icb)) ), 1:14 );

Upvotes: 3

gnovice
gnovice

Reputation: 125854

This is one of those problems that can be solved in many different ways. First, I'll give you the solution that most directly answers what you asked with the least amount of modification to your existing code...

The set and get functions can operate on vectors of handles, so you can reduce it all to just one function call to set everything. If you only want to set the checkboxes that were previously checked (assuming that the remaining are unchecked by default) you can use your stored checkbox states as a logical index into a vector of your checkbox handles:

cbHandles = [handles.checkbox1 handles.checkbox2 ... handles.checkbox14];  % All handles
cbStates = [checkbox1 checkbox2 ... checkbox14];  % All states
set(cbHandles(logical(cbStates)), 'Value', 1);

Alternatively, you can just set all the states (checked or unchecked) as follows:

set(cbHandles, {'Value'}, num2cell(cbStates(:)));

As you can see, this will be made easier if you store your checkbox handles and states each as a vector instead of multiple variables.


Alternatives

Here are some alternative ways to solve or improve this, which will require a bit more modification of your existing code:

Window visibility

Instead of repeatedly opening and closing the window with your checkboxes, you could simply create it once, then adjust its 'Visibility' property to make it appear and disappear. Even when not visible, all of the window components (i.e. checkboxes) still exist and their states can be accessed using the handles stored in your handles structure. This avoids the need to store their states in global variables or set their states when reopening the window.

Avoid the globals

The handles structure, contrary to its name (since it could be named whatever you want) is just a regular structure that can store any data, not just graphics handles. In your closing function (or wherever you are storing the checkbox states before closing), you can just add the states to the handles structure:

handles.cbStates = get(handles.cbHandles, 'Value');
guidata(hObject, handles);

This assumes your checkbox handles are stored in a vector cbHandles. You would then update the states in your opening function as follows:

set(handles.cbHandles, {'Value'}, handles.cbStates);

Upvotes: 3

Related Questions