MATLAB Answers


Return data from GUIDE on figure close

Asked by Brian Lause on 13 Sep 2019 at 21:02
Latest activity Commented on by Image Analyst
on 14 Sep 2019 at 1:18
I have a GUIDE generated UI in which I have wired up one of computed values, to handles and return it through automatically generated callback OutputFcn. When I run my UI, it computes the value and returns it to the command window immediately. The UI has interactive controls which will modify the output value, but it is not returned after the interactive controls are manipulated.
When I add uiwait(handles.figure1), then OutputFcn is not called until close, which is the desired behavior. Unfortunately when I do this the handles passed into OutputFcn is empty. When I omit the uiwait command from OpeningFcn, then the handles object passed to OutputFcn is populated as expected.
It seems that if OutputFcn is called while the figure is still open, then the handles object exists and can be referenced, however, if OutputFcn is not called until I close the figure, then the handles object points to a closed figure and I can no longer reference it.
Any advice to resolve this? Thanks!


Sign in to comment.

2 Answers

Answer by Adam Danz
on 13 Sep 2019 at 21:08
Edited by Adam Danz
on 14 Sep 2019 at 0:17
 Accepted Answer

To delay a GUIDE-GUI output until the GUI is closed, follow these steps. A functional demo is attached that produces an empty GUI and returns a hard-coded output when the GUI is closed. See comments in the m-file for help.
1) If your GUI does not already have a close request function, add one from within GUIDE by opening your GUI in GUIDE, right click the figure background, select View Callbacks, and the select CloseRequestFcn.
2) In the ..._OpeningFcn
function demoGui_OpeningFcn(hObject, eventdata, handles, varargin)
. . .
uiwait(); % add this to the end
3) In the ..._outputFcn
function varargout = demoGui_OutputFcn(hObject, eventdata, handles)
varargout{1} = handles.output;
delete(hObject); % add this
4) In the ..._CloseRequestFcn you created from GUIDE,
function figure1_CloseRequestFcn(hObject, eventdata, handles)
% delete(hObject); % Remove this
handles.output = 3.1415926; % Produce or grab your outputs
guidata(hObject, handles); % Store the outputs in the GUI
uiresume() % resume UI which will trigger the OutputFcn
[Original answer has been edited]


Adam Danz
on 13 Sep 2019 at 23:08
Not for me. I have nothing else in either of those 3 functions listed in the bullet points above. When I press the red 'x' to close the window, it closes. Of course you won't be able to close it using the close() command from the command window since the uiwait is preventing any subsequent commands. If you're using a custom 'close' button, that may operate differently and may require it's own delete(hobject) command.
Brian Lause on 13 Sep 2019 at 23:10
I missed that you moved the delete from the CloseRequest to the Output. This now works as I would like. Thank you very much, you are a wizard!
Adam Danz
on 13 Sep 2019 at 23:16
If I were a wizard I would have understood your question from the getgo!
Glad I could help.
I'll update my answer so it's more useful.

Sign in to comment.

Answer by Image Analyst
on 13 Sep 2019 at 22:27

Below is a close request function I use in one project. Adapt as needed:
% --- Executes when user attempts to close figMainWindow.
function figMainWindow_CloseRequestFcn(hObject, eventdata, handles)
% hObject handle to figMainWindow (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
% Hint: delete(hObject) closes the figure
global vidobj; % Video camera object.
% Save the current settings to our disk file.
SaveUserSettings(handles, true);
% Shut down the camera
% Get rid of variables from the global workspace so that they aren't
% hanging around the next time we try to run this m-file.
clear global;
catch ME
callStackString = GetCallStack(ME);
errorMessage = sprintf('Error in program %s.\nTraceback (most recent at top):\n%s\nError Message:\n%s', ...
mfilename, callStackString, ME.message);
set(handles.txtInfo, 'string', errorMessage);
fprintf(1, '\n================= Exited figMainWindow_CloseRequestFcn. =================\n');
return; % from figMainWindow_CloseRequestFcn()


Brian Lause on 13 Sep 2019 at 22:56
I think this does not return any data to the command line which can be captured as a variable. That is my goal.
Adam Danz
on 13 Sep 2019 at 23:03
At the risk of sounding pedantic, the outputFcn returns the output to whatever workspace called the GUI. So if you call the GUI from the command window and included an output, the variable will be assigned to the base workspace. If the GUI is called from another function, the output is assigned to that function's workspace. Just FYI.
Image Analyst
on 14 Sep 2019 at 1:18
I mainly use the close request function to capture situations where the user tries to shutdown the GUI via the x in the upper left of the title bar instead of from an "Exit" button I placed on the GUI. If the user does that (clicks on the X), and you don't have a close request function then the app will shutdown immediately, and if you had any shutdown or cleanup code in the exit button's callback function, then that code won't get implemented, for example shutting down camera(s) or other hardware, closing Excel workbooks, shutting down timers, or whatever you may want to do.
I just checked, and it seems like the OutputFcn() gets called immediately after the OpeningFcn() but does not get called during or after the CloseRequestFcn function, or if you delete the GUI's variable via a call to delete(). It's a good idea to put fprintf's in there so you know what functions get called when. For example:
% Print informational message so you can look in the command window and see the order of program flow.
fprintf('Just entered myApp_OutputFcn...\n');
% Get default command line output from handles structure
varargout{1} = handles.output;
% More code if you want....
% Maximize the window via undocumented Java call.
% Reference:
catch ME
% Some error happened if you get here.
callStackString = GetCallStack(ME);
errorMessage = sprintf('Error in program %s.\nTraceback (most recent at top):\n%s\nError Message:\n%s',...
mfilename, callStackString, ME.message);
% Print informational message so you can look in the command window and see the order of program flow.
fprintf('Now leaving myApp_OutputFcn...\n');

Sign in to comment.