From: Gerbil Gerbil on
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
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
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
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
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