From: Gerbil Gerbil on 7 Jun 2010 14:37 Hi Everyone, I've been tinkering with this for the past few days and not getting anywhere. Since posting, I've spent a lot of time trying to update my GUIDE GUI with uiwait() where it tells me to put it in the function, and putting uiresume() in various places. I thought it might make some sense to mess around with putting varargout as one of the returns for my last callback, since it seems to be getting the values I'm trying to pass it, but that just makes the program error out. I'd really appreciate any help I can get, so I can at least stop the random google searches that only seem to lead to irrelevant matlab help pages. Here's the rest of my earlier post: +++++++++++++++++++++++++++++++++++++++++++++++++++++++ I'm trying to design a GUI that I can run from a script, returning the values entered by the user back to the script for further processing. My problem is that I can't seem to get my values back through their varargout. I've tried tinkering with the output function, but it hasn't fixed anything. I've tried putting something in here to test the output, and it successfully updates handles.output to 'test output', so I know the problem isn't that it's not returning it: > function varargout = myFunction_OutputFcn(hObject, eventdata, handles) > handles.output = 'test output'; % to test the output > varargout{1} = handles.output; It works, but if I try to update handles.output by updating the handles variable using my other callbacks, it doesn't seem to be getting back to the main function: > function varargout = myGUI(varargin) It seems to me that the main function (myGUI) expects a return from myFunction_OutputFcn before any of my other callbacks can do their updating of the variables by the user, so it's tripping over trying to provide a handles.output that isn't being provided by the handles input. I know that the rest of handles being passed between the callbacks are working, since I am able to display the updated variables in a msgbox triggered by a user pressing a push button. I'm just not entirely sure how it is that all my other functions can pass handles to each other perfectly well, while this output function isn't getting updated in the same way. I'd really appreciate any advice on this, Laura
From: Walter Roberson on 7 Jun 2010 15:10 Gerbil Gerbil wrote: >> function varargout = myFunction_OutputFcn(hObject, eventdata, handles) >> handles.output = 'test output'; % to test the output >> varargout{1} = handles.output; > It works, but if I try to update handles.output by updating the > handles variable using my other callbacks, it doesn't seem to be > getting back to the main function: This reminds me of why I don't use GUIDE ;-) >> function varargout = myGUI(varargin) > It seems to me that the main function (myGUI) expects a return from > myFunction_OutputFcn before any of my other callbacks can do their > updating of the variables by the user, so it's tripping over trying to > provide a handles.output that isn't being provided by the handles > input. > I know that the rest of handles being passed between the callbacks are > working, since I am able to display the updated variables in a msgbox > triggered by a user pressing a push button. In your program, what signals that the computation has completed and the program is ready to return the value? Typically the arrangement would be that the OpeningFcn function creates a figure that has a uicontrol that has a callback that deletes the figure; if that mechanism is used, then you would uiwait() or waitfor() the figure handle. However, in such an arrangement, the handles structure created by GUIDE is stored as application data in the figure (that's what guidata() does internally), and of course once the figure is deleted that application data does not exist. Therefore, one must arrange to save off the application data before deleting the figure. That could, for example, be done by a nested variable: function myGUI(varargin) output_data = []; function myOpeningFcn(hObject, eventdata, handles) ... figure(1999); set(1999, 'CloseRequestFcn', {@myClosingFcn}) uicontrol('Style', 'pushbutton', 'Callback', {@myDoSomethingFcn})) ... uiwait(1999); end function myDoSomethingFcn(varargin) ... %do the actual work src = varargin{1}; handles = guidata(src); output_data = handles.output; end varargout = function myFunction_OutputFcn(varargin) varargout{1} = output_data; end end Notice that the functions are nested inside the myGUI function. This is necessary in order to get the shared nested variable to work.
From: Gerbil Gerbil on 7 Jun 2010 16:07 On Jun 7, 3:10 pm, Walter Roberson <rober...(a)hushmail.com> wrote: > Gerbil Gerbil wrote: > >> function varargout = myFunction_OutputFcn(hObject, eventdata, handles) > >> handles.output = 'test output'; % to test the output > >> varargout{1} = handles.output; > > It works, but if I try to update handles.output by updating the > > handles variable using my other callbacks, it doesn't seem to be > > getting back to the main function: > > This reminds me of why I don't use GUIDE ;-) > > >> function varargout = myGUI(varargin) > > It seems to me that the main function (myGUI) expects a return from > > myFunction_OutputFcn before any of my other callbacks can do their > > updating of the variables by the user, so it's tripping over trying to > > provide a handles.output that isn't being provided by the handles > > input. > > I know that the rest of handles being passed between the callbacks are > > working, since I am able to display the updated variables in a msgbox > > triggered by a user pressing a push button. > > In your program, what signals that the computation has completed and the > program is ready to return the value? Typically the arrangement would be that > the OpeningFcn function creates a figure that has a uicontrol that has a > callback that deletes the figure; if that mechanism is used, then you would > uiwait() or waitfor() the figure handle. However, in such an arrangement, the > handles structure created by GUIDE is stored as application data in the figure > (that's what guidata() does internally), and of course once the figure is > deleted that application data does not exist. Therefore, one must arrange to > save off the application data before deleting the figure. That could, for > example, be done by a nested variable: > > function myGUI(varargin) > output_data = []; > > function myOpeningFcn(hObject, eventdata, handles) > ... > figure(1999); > set(1999, 'CloseRequestFcn', {@myClosingFcn}) > uicontrol('Style', 'pushbutton', 'Callback', {@myDoSomethingFcn})) > ... > uiwait(1999); > end > > function myDoSomethingFcn(varargin) > ... %do the actual work > src = varargin{1}; > handles = guidata(src); > output_data = handles.output; > end > > varargout = function myFunction_OutputFcn(varargin) > varargout{1} = output_data; > end > end > > Notice that the functions are nested inside the myGUI function. This is > necessary in order to get the shared nested variable to work. Thanks for the tips. Right now I'm using a push button to get things to start: % --- Executes on button press in begin_exp. function begin_exp_Callback(hObject, eventdata, handles) % hObject handle to begin_exp (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) % handles = guidata(hObject); uiresume; close(gcbf) I know this is running, since if I put a msgbox() command in it, it shows up. In addition, if I put something that's been updated in my handles structure into it, that shows up with the correct most updated value. Right now I'm just using the default main function: function varargout = myGUI(varargin) %myGUIM-file for myGUI.fig % myGUI, by itself, creates a new myGUIor raises the existing % singleton*. % % H = myGUIreturns the handle to a new myGUIor the handle to % the existing singleton*. % % myGUI('Property','Value',...) creates a new myGUIusing the % given property value pairs. Unrecognized properties are passed via % varargin to myGUI_OpeningFcn. This calling syntax produces a % warning when there is an existing singleton*. % % myGUI('CALLBACK') and myGUI('CALLBACK',hObject,...) call the % local function named CALLBACK in myGUI.M with the given input % arguments. % % *See GUI Options on GUIDE's Tools menu. Choose "GUI allows only one % instance to run (singleton)". % % See also: GUIDE, GUIDATA, GUIHANDLES % Edit the above text to modify the response to help myGUI % Begin initialization code - DO NOT EDIT gui_Singleton = 1; gui_State = struct('gui_Name', mfilename, ... 'gui_Singleton', gui_Singleton, ... 'gui_OpeningFcn', @myGUI_OpeningFcn, ... 'gui_OutputFcn', @myGUI_OutputFcn, ... 'gui_LayoutFcn', [], ... 'gui_Callback', []); if nargin && ischar(varargin{1}) gui_State.gui_Callback = str2func(varargin{1}); end if nargout [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:}); else gui_mainfcn(gui_State, varargin{:}); end % End initialization code - DO NOT EDIT I think you're right; in a lot of my debugging I'm getting errors here: if nargout [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:}); end I'll see if nesting the OpeningFcn in the main function fixes it. Fingers crossed. -Laura
From: Walter Roberson on 7 Jun 2010 17:46 Gerbil Gerbil wrote: > Right now I'm using a push button to get things to start: > % --- Executes on button press in begin_exp. > function begin_exp_Callback(hObject, eventdata, handles) > % handles = guidata(hObject); > uiresume; > close(gcbf) That's going to delete the figure window, which is good news for uiwait() but, as I mentioned earlier, bad news for keeping the handles structure. > function varargout = myGUI(varargin) > gui_Singleton = 1; > gui_State = struct('gui_Name', mfilename, ... > 'gui_Singleton', gui_Singleton, ... > 'gui_OpeningFcn', @myGUI_OpeningFcn, ... > 'gui_OutputFcn', @myGUI_OutputFcn, ... > 'gui_LayoutFcn', [], ... > 'gui_Callback', []); > if nargin && ischar(varargin{1}) > gui_State.gui_Callback = str2func(varargin{1}); > end > > if nargout > [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:}); > else > gui_mainfcn(gui_State, varargin{:}); > end > % End initialization code - DO NOT EDIT I would probably need to see gui_mainfcn() to debug further. begin_exp and myGui_outputFcn are the two functions that need to be nested in the same routine in order to share variables. I have a _suspicion_ that the documented description of gui_OutputFcn is misleading, and that it is run before the gui_mainfcn() returns, not after myGUI returns. Running it before would be much more natural for the purposes of getting access to the handle without needing to bother about nested variables. I have not, however, fired up GUIDE for several years, so I'm talking in terms of "sensible", which might not be what actually happens.
From: Gerbil Gerbil on 8 Jun 2010 14:24 On Jun 7, 5:46 pm, Walter Roberson <rober...(a)hushmail.com> wrote: > Gerbil Gerbil wrote: > > Right now I'm using a push button to get things to start: > > % --- Executes on button press in begin_exp. > > function begin_exp_Callback(hObject, eventdata, handles) > > % handles = guidata(hObject); > > uiresume; > > close(gcbf) > > That's going to delete the figure window, which is good news for uiwait() but, > as I mentioned earlier, bad news for keeping the handles structure. > > > > > function varargout = myGUI(varargin) > > gui_Singleton = 1; > > gui_State = struct('gui_Name', mfilename, ... > > 'gui_Singleton', gui_Singleton, ... > > 'gui_OpeningFcn', @myGUI_OpeningFcn, ... > > 'gui_OutputFcn', @myGUI_OutputFcn, ... > > 'gui_LayoutFcn', [], ... > > 'gui_Callback', []); > > if nargin && ischar(varargin{1}) > > gui_State.gui_Callback = str2func(varargin{1}); > > end > > > if nargout > > [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:}); > > else > > gui_mainfcn(gui_State, varargin{:}); > > end > > % End initialization code - DO NOT EDIT > > I would probably need to see gui_mainfcn() to debug further. > > begin_exp and myGui_outputFcn are the two functions that need to be nested in > the same routine in order to share variables. > > I have a _suspicion_ that the documented description of gui_OutputFcn is > misleading, and that it is run before the gui_mainfcn() returns, not after > myGUI returns. Running it before would be much more natural for the purposes > of getting access to the handle without needing to bother about nested > variables. I have not, however, fired up GUIDE for several years, so I'm > talking in terms of "sensible", which might not be what actually happens. I tried what you suggested, putting those functions in myGUI, but all I seemed to be able to do was crash Matlab, so I'm assuming I put them in the wrong place. I'm assuming your description is correct about gui_OutputFcn and gui_mainfcn, in that that the gui_OutputFcn runs before main, but I haven't managed to work out the correct ordering of variables, functions, etc. Given that I've spent half a week of work on this problem, I took up the advice of a co-worker and just saved the variables in a mat file, and loaded them from my script that was loading the GUI in the first place. Maybe if I have some more time I'll see if I can work out a more graceful way to do this. I really hate to implement such bad coding practices, but sometimes things just need to work. :-\ Thanks for all the help in understanding these functions. Laura
|
Pages: 1 Prev: getframes from imagesc w/ a custom colormap Next: mxGetPr size as double* |