There are three tweaks you will need to make this work, if you made your GUI using the GUIDE functionality in Matlab (note if you want to tinker with an example, I've included one at the end of this post).
1) Make the GUI wait before it returns outputs
The GUI will try to return outputs right when it is invoked, well before any of the values can be specified by the user. To block such behavior, you can pause program execution using the uiwait command at the end of OpeningFcn:
uiwait(hObject);This will make the GUI wait until some additional action is performed (e.g., uiresume is called to resume program flow, or the GUI (with handle hObject) is closed). This gives the user time to enter the actual values. Note you should put this command at the end of OpeningFcn.
2) Specify the output variables
Within OutputFcn, use varargout to specify what outputs you want returned from the GUI. Something like:
varargout{1} = handles.data1;Matlab typically passes information among the different elements of a GUI using the handles variable, so this code just exploits this fact. Once the outputs are specified as above, they will be returned as outputs to the calling function for the main GUI:
varargout{2} = handles.data2;
[data1, data2]=GUI_Practice;Where GUI_Practice is the name of the m-file that defines the GUI.
Caveat: you will probably define the desired outputs (such as handles.data1) within a callback function (using something like handles.data1=x). When you do so, be sure to enter the following within the callback function:
guidata(hObject, handles);This saves the local variable handles to the GUI handle, so they will not be annihilated outside the scope of the callback function.
3) Tell the program when to resume
If you only did the above steps, after calling uiwait the program would hang indefinitely. You need to call the uiresume command to bump the program out of wait mode. To resume program flow when the user clicks Start Program, add uiresume to CloseRequestFcn:
%When user clicks button, check to see if GUI is in wait %mode. If it is, resume program; otherwise close GUINote: you should also add the line delete(hObject); to the end of outputFcn. Otherwise, the user will have to attempt to close the GUI twice: once to resume program flow with uiresume, and again to close the GUI with delete.
if isequal(get(hObject, 'waitstatus'), 'waiting')
uiresume(hObject);
else
delete(hObject);
end
Example
Below is a simple example called GUI_Practice (m-file and fig file are both needed for this to run, as it was made with GUIDE). Once the files are in your Matlab path, you can instantiate the GUI by entering animal_name=GUI_Practice;
GUI_Practice.m
GUI_Practice.fig
Acknowledgment
I got some of the ideas for this from Mathworks (here). If you are having trouble getting it to work, let me know in the comments, and I'll try to help.
6 comments:
Thanks for this tip. It was very helpful.
I also wanted to point out that it matters where you put the uiwait command. You should put it at the very end of the OpeningFcn function, or the output for the GUI might not update properly (and will output the initialization value of your variable).
I learned this through an hour of frustration today.
Anon I have added that detail to the post: thanks for the tip.
I've done all the steps and checked the code dozens of times and still get an error:
Attempt to reference field of non-structure array.
Error in GUI_input_parameter>GUI_input_parameter_OutputFcn (line 74)
varargout{1} = handles.data1;
Error in gui_mainfcn (line 263)
[varargout{1:nargout}] = feval(gui_State.gui_OutputFcn, gui_hFigure, [], gui_Handles);
Error in GUI_input_parameter (line 40)
[varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
______
The details of the error are here (http://fr.mathworks.com/matlabcentral/newsreader/view_thread/338273) if anyone would care to take a look.
Anyways, thank you very much for the tutorial. Without it I couldn't have got so far with my code
Anon: did you try the example I include in the post, and did it work?
I will take a look at your post when I get some time this weekend.
Anon: a couple of things:
1. I'd recommend simplifying your example to just have one datum you want to pull instead of five. That is, create the simplest possible code that reproduces your problem. This will make it easier for everyone to figure out the problem.
2. You should include a link to the .fig file you are using. Without the '.fig' file, it is not possible to recreate the problem.
Okay, I'll do as you suggested as soon as I can. Thank you for your help.
Post a Comment