Is this a switchyarding case?

I have a figure with 4 checkboxes. I want to fill a 1x4 array with values of 1 if the checkbox is selected. What I've written below somewhat works, but only allows one value of chkbxvals to change and won't keep any previous values. All four checkboxes use the same callback.
So for example, if the user clicks on all four boxes, I want chkbxvals = [1 1 1 1]. If the user unchecks the first box, chkbxvals = [0 1 1 1]. If none are selected, then chkbxvals = [0 0 0 0]; and so on...
I know the long way to do this is to create 16 loops to cover all possible situations, but I feel as though there may be a more compact way to do it.
function input_chkbx_Callback(gcf,eventdata,handles,chkbxval)
chkbxvals = [0 0 0 0];
switch chkbxval
case 1
chkbxvals(1) = 1;
case 2
chkbxvals(2) = 1;
case 3
chkbxvals(3) = 1;
case 4
chkbxvals(4) = 1;
end
Thanks!

 Risposta accettata

Matt Fig
Matt Fig il 14 Apr 2011
Here is an example.
function [] = Check_examp()
% Print to screen the users checkbox choices.
S.fh = figure('units','pixels',...
'position',[500 500 200 220],...
'menubar','none',...
'name','Check_boxes',...
'numbertitle','off',...
'resize','off');
S.ch(1) = uicontrol('style','check',...
'unit','pix',...
'position',[10 60 180 20],...
'fontsize',14,...
'string','checkbox1');
S.ch(2) = uicontrol('style','check',...
'unit','pix',...
'position',[10 100 180 20],...
'fontsize',14,...
'string','checkbox2');
S.ch(3) = uicontrol('style','check',...
'unit','pix',...
'position',[10 140 180 20],...
'fontsize',14,...
'string','checkbox3');
S.ch(4) = uicontrol('style','check',...
'unit','pix',...
'position',[10 180 180 20],...
'fontsize',14,...
'string','checkbox4');
S.pb = uicontrol('style','push',...
'units','pix',...
'position',[10 10 180 40],...
'fontsize',14,...
'string','Get Boxes',...
'callback',{@pb_call,S});
function [] = pb_call(varargin)
% Callback for pushbutton, gets checkbox choices.
S = varargin{3}; % Get the structure.
V = cell2mat(get(S.ch(4:-1:1),'value')) % Get the users choice.
.
.
.
Note that if you are using GUIDE, you should modify the code in the callback by getting the handles to the checkboxes into a single vector when querying their value property. Something like:
S =[handles.ch1,handles.ch2,handles.ch3,handles.ch4];
V = cell2mat(get(S,'value'))
Also, note that I put the code in the callback to a pushbutton, but you can put it anywhere.

13 Commenti

Matt Fig
Matt Fig il 14 Apr 2011
Somehow, we are back to the 2 second delay between typing and preview window since TMW updated Answers....
Iman Alsharkawi
Iman Alsharkawi il 14 Apr 2011
It looks as though in my script I have to make sure that the pushbutton uicontrol would have to be defined AFTER the checkbox uicontrols? Is there a way to make this work so I can define the button before the checkboxes? Only reason I ask is to preserve the tab order on the screen... unless there's a way to add a sequential tab identity to all the uicontrol handles...
Matt Fig
Matt Fig il 14 Apr 2011
You can define your pushbutton after the checkboxes, but if you are saving your data in a structure like I did you will have to define the callback for the pushbutton after all uicontrols have been created. That way the entire structure will exist in the callback.
Matt Fig
Matt Fig il 14 Apr 2011
So simply define the uicontrols in any order you want, just don't assign the callbacks until the end.
set(S.pb,'callback',{@pb_call,S}) % After all uicontrols are created.
Iman Alsharkawi
Iman Alsharkawi il 14 Apr 2011
Thank you, Matt. That clears up why the callbacks were set separately from the uicontrols in some of the examples provided in the 'Matlab Advanced GUI Development' book. I see the light! =)
Iman Alsharkawi
Iman Alsharkawi il 14 Apr 2011
Actually, I have another question...
Let's say if the button was pushed, you get V. if you push the button again and this time V is different from the previous V, I want to prompt the user with a dialog asking if the want to save the previous V. How do I do that?
(sort of like this example, but I put in a msgbox instead of a questdlg).
function [] = load_excel_data_button_Callback(varargin)
C = varargin{3}; %get the structure(hObject, eventdata, handles)
if nargout < 1
msgbox('Do you want to save the previous load?')
else
callsheet = cell2mat(get(C.inputchkbx(4:-1:1),'value'))
end
Matt Fig
Matt Fig il 14 Apr 2011
The way you have defined that callback, nargout is always 0, but anyway...
Are you asking how to save the previous V? One way would be to add to the structure a field called S.V = []. in your initialization code. Then in the callback you change two things. Check if S.V is empty, if so don't prompt, and assign S.V the new value. If it is not empty, prompt the user. Then at the end of the callback you will need to update the structure for the next call to the callback. This assures that the new value of S.V is preserved:
set(S.pb,'callback',{@pb_call,S})% At end of callback. Updated S...
Iman Alsharkawi
Iman Alsharkawi il 14 Apr 2011
??? Reference to non-existent field 'V'.
Could you show me where that would be placed based on the example you showed? I'm obviously missing something...
Matt Fig
Matt Fig il 14 Apr 2011
Yes, (as I said above) put:
S.V = [];
in the initialization code. This means put it in the part of the code that creates the GUI, even before S.fh if you wish.
Iman Alsharkawi
Iman Alsharkawi il 14 Apr 2011
Hmmm... I have that, but I still have errors with referencing non-existent fields. I'm new to the whole GUI experience, so I'll have to play with this some more tonight. Could you possibly link me to a basic example of doing this sort of thing (if there is one?).
Matt Fig
Matt Fig il 14 Apr 2011
You don't say where the errors are... or when the come. Feel free to contact me regarding this code. There are many examples of this type of problem in here:
http://www.mathworks.com/matlabcentral/fileexchange/24861-41-complete-gui-examples
Iman Alsharkawi
Iman Alsharkawi il 14 Apr 2011
Thanks for the GUI examples! I'll email you about the issue I had with GUI_41 later... but in the meantime...
This is my callback function (to that example you gave me above):
function [] = pb_call(varargin)
% Callback for pushbutton, gets checkbox choices.
S = varargin{3}; % Get the structure.
S.V;
switch isempty(S.V)
case 1
V = cell2mat(get(S.ch(4:-1:1),'value')) % Get the users choice.
otherwise
msgbox('enter prompt box here')
end
S.V = V;
set(S.pb,'callback',{@pb_call,S})
I'm getting an error with the S.pb... ??? Reference to non-existent field 'pb'.
Matt Fig
Matt Fig il 14 Apr 2011
Oh, I see what happened. S does not have a field called pb when the callback is created! Use this instead:
set(gcbo,'callback',{@pb_call,S})
Or go back and initialize S.pb, then in a separate line assign the callback with:
set(S.pb,'callback',{@pb_call,S})

Accedi per commentare.

Più risposte (1)

Walter Roberson
Walter Roberson il 14 Apr 2011

0 voti

What is the Callback property set to for these checkboxes? Callbacks do not take 4 inputs unless the Callback property has been set up specially, and the typical way of doing so would end up with the 4th argument always being the same as the value was when the callback property was set.

1 Commento

Iman Alsharkawi
Iman Alsharkawi il 14 Apr 2011
handles.first_chkbx = ...
uicontrol('Parent',handles.input_panel,...
'style','checkbox','units','normalized',...
'position',...
[xp01+0.002+ds21 yp03+dyp03-2*ds2-3*hbutton2 wbutton2 hbutton]);
set(handles.first_chkbx,...
'Callback',{@input_chkbx_Callback,handles,1});
handles.second_chkbx = ...
uicontrol('Parent',handles.input_panel,...
'style','checkbox','units','normalized',...
'position',...
[xp01+0.002+ds21 yp03+dyp03-2*ds2-3*hbutton2 wbutton2 hbutton]);
set(handles.second_chkbx,...
'Callback',{@input_chkbx_Callback,handles,2});
and so on...

Accedi per commentare.

Categorie

Community Treasure Hunt

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

Start Hunting!

Translated by