Calling a function from within a GUI (GUIDE)

%Psuedo Code example of what I'm trying to do
%Guide auto generated code here
%Radio Button Group
function FuncSetA_SelectionChangeFcn(hObject, eventdata, handles)
%Get numbers from user input into edit boxes
Edit_Box1 = get(str2double(get(handles.Edit_Box1,'string'));
Edit_Box2 = get(str2double(get(handles.Edit_Box2,'string'));
%Add or subtract the numbers from the Edit_boxes
switch get(eventdata.NewValue,'Tag') % Get Tag of selected object.
case 'add'
%For example: A = Edit_Box1 + Edit_Box2
case 'subtract'
%For example: B = Edit_Box1 - Edit_Box2
end
%Edit Box 1 uicontrol
function Edit_Box1_Callback(hObject, eventdata, handles)
%Edit Box 2 uicontrol
function Edit_Box2_Callback(hObject, eventdata, handles)
Pushbutton to display(A or B)
EOF
Question: This pseudo code works the first time I run it. However, if I change the edit box values and hit pushbutton to display A, it does not run the SelectChangeFcn again and thus does not update the values. I must change the edit box values, then toggle back and forth with the radio buttons and then hit the pushbutton to get it to display the correct answer.
Is there a way to force the code to run the SelectChangeFcn every time I hit the pushbutton (or equivalent)? That is I need it to update Edit_box1 and 2 values add them and then display upon the pushbutton call.

 Respuesta aceptada

Image Analyst
Image Analyst el 4 de Nov. de 2012
Regarding your last comment: Who cares? There is a lot of boilerplate code, especially near the beginning of the m-file. Just don't worry about it. Like I said, ignore eventdata and hObject just like you ignore all the boilerplate code at the top of the file. And who cares if you can't put code in the individual callback for a particular radio button. You can do it in the group callback, like the code I gave you:
if get(handles.radioButton1, 'value')
% Do whatever you want to do if radio button 1 is selected.
elseif get(handles.radioButton2, 'value')
% Do whatever you want to do if radio button 2 is selected.
end
No, you're not "the first to have auto generated a buttongroup in GUIDE and then needed to call it from a pushbutton." I do it all the time using code like above. It works, so I don't want to get into a philosophical discussion with them about why it should, perhaps, be done in separate, individual callbacks.
When you say " Surely there is some simple work around.", why don't you consider putting your code in the group callback a workaround, or an acceptable workaround? It doesn't do it the way you think it should (separate, individual callbacks), and you don't like the group callback workaround. What kind of other workaround would you like that would be better?

Más respuestas (1)

John Petersen
John Petersen el 1 de Nov. de 2012

1 voto

The functions in your program created by guide can be called like any other function. You just have to input the arguments it needs. I suggest you call the selectchange fcn from the pushbutton function, but you'll need to include the arguments it asks for.

8 comentarios

Brad
Brad el 1 de Nov. de 2012
Thanks all give it a try.
Nope, didn't work. Here is an example from the code and the error message that was generated:
%This is my SelectChangeFcn radiobutton group
function FuncSetA_SelectionChangeFcn(hObject, eventdata, handles)
switch get(eventdata.NewValue,'Tag') % Get Tag of selected object.
case 'Sinc'
% Code for when sinc radio button is selected.
Store output from this in 'UserData' field of this radio button group
==============================================================
case 'Hat'
% Code for when hat radiobutton2 is selected.
Store output from this in 'UserData' field of this radio button group
==============================================================
%more code...
%This is the pushbutton callback
function Pushbutton_Callback(hObject, eventdata, handles)
%!!This is where I try to call the SeclectChangeFcn!!
FuncSetA_SelectionChangeFcn(hObject, eventdata, handles)
%Get data from the 'UserData' field of FuncSetA radio buttons
FuncSetA = get(handles.FuncSetA,'UserData');
...more code...
=================================================================================== Here is the error message generated. ================================================================================== ??? Attempt to reference field of non-structure array.
Error in ==> Explore_FT>FuncSetA_SelectionChangeFcn at 103 switch get(eventdata.NewValue,'Tag') % Get Tag of selected object.
Error in ==> Explore_FT>PLOT_Callback at 576 FuncSetA_SelectionChangeFcn(hObject, eventdata, handles)
Error in ==> gui_mainfcn at 96 feval(varargin{:});
Error in ==> Explore_FT at 42 gui_mainfcn(gui_State, varargin{:});
Error in ==> @(hObject,eventdata)Explore_FT('PLOT_Callback',hObject,eventdata,guidata(hObject))
??? Error while evaluating uicontrol Callback ================================================================================== I feel like there is probably some simple fix, but I'm pretty new to GUI. If my question is unclear or if this is not enough info (the actual code is pretty lengthy so I've cut a lot of stuff that could be important) I apologize and will try to find someone local here to help me. I don't want to waste people's time.
Thanks for the help.
Brad
You never need to mess with hObject or eventdata. Just access whatever control you want, even radio buttons, via their actual handle. So don't get the 'tag' of eventdata.newvalue, just check the radio button directly:
if get(handles.radioButton1, 'value')
% Do whatever you want to do if radio button 1 is selected.
elseif get(handles.radioButton2, 'value')
% Do whatever you want to do if radio button 2 is selected.
end
Brad
Brad el 4 de Nov. de 2012
I see the problem that using eventdata creates when you try to call that function from the pushbutton callback. However, my question is, if using event data is not a good thing to do, why did GUIDE auto generate this code? Further, when I try to view the callback for the individual radiobuttons it tells me that I cannot see these callbacks and should only modify the auto generated SelectChangeFcn (which uses eventdata). Surely there is some simple work around. I cannot be the first to have auto generated a buttongroup in GUIDE and then needed to call it from a pushbutton. Thoughts?
John Petersen
John Petersen el 6 de Nov. de 2012
Editada: John Petersen el 6 de Nov. de 2012
@Image Analyst: on never needing to mess...: What if you want to perform the functions of a certain button(or several) automatically with another button? Seems like the simplest thing is to call the callback function for the button of interest. His original question was to know if there was a way to force calling the select function using a different button.
Image Analyst
Image Analyst el 6 de Nov. de 2012
The way I handle that (no pun intended) is to have a separate custom function that I wrote myself, which takes handles as an input, and, if it made any changes to handles, return it as an output so guidata() can later update the handles structure globally. So you don't have one call back call another callback, say button1_click() call button2_click which does stuff, I have button1_click() and button2_click both call a separate function called A_button_was_clicked(handles). Then this function gets called by both functions and does what you want it to do - what button2_click would have done. This avoids the problem and confusion that might happen if button1_click called button2_click directly and so the hObject and eventdata that button 2 thought it was getting from GUIDE and related to button2 actually came from button 1. I can just see that having potential for problems so my method avoids the issue by not using them at all, which is fine because they're never needed anyway.
John Petersen
John Petersen el 6 de Nov. de 2012
That makes a lot of sense. Thanks!
Thanks for this post. In the future, I will try creating a separate function that takes handles as an input and, if it made changes to handles, return it as an output so guidata() can later update the handles structure.
However, following Image Analyst's post on Nov 4 18:24, I cut the following code:
switch get(eventdata.NewValue,'Tag') % Get Tag of selected object.
case 'add'
%For example: A = Edit_Box1 + Edit_Box2
case 'subtract'
%For example: B = Edit_Box1 - Edit_Box2
end
And replaced it with
if get(handles.radioButton1, 'value')
% Do whatever you want to do if radio button 1 is selected.
elseif get(handles.radioButton2, 'value')
% Do whatever you want to do if radio button 2 is selected.
end
That is, I got rid of the auto generated code and replaced it with the suggested switchyard style. The code now works fine, it simply required a lot of reworking of the code. Thank you again, everyone who contributed to this thread.

Iniciar sesión para comentar.

Categorías

Más información sobre Interactive Control and Callbacks en Centro de ayuda y File Exchange.

Preguntada:

el 31 de Oct. de 2012

Community Treasure Hunt

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

Start Hunting!

Translated by