Clearing object from base workspace on closing a GUI

I'm buidling a GUI with the following structure:
classdef App < handle
properties
gui
other_properties
end
methods
function obj = App()
% Initialize window
obj.gui = obj.main_window_layout('reuse');
% Assign callbacks
obj.assign_callbacks();
end
end
end
The main windows layout is defined in:
function h1 = main_window_layout(obj,policy)
%% policy - create a new figure or use a singleton. 'new' or 'reuse'.
persistent hsingleton;
if strcmpi(policy, 'reuse') & ishandle(hsingleton)
h1 = hsingleton;
return;
end
%% Create the figure instance
% Define position [x bottom left, y bottom left, width, height]
figure_position = [10 10 112 32.3076923076923];
h1 = figure(...
'PaperUnits','inches',...
'Units','characters',...
'Position',figure_position);
%% Additional uicontrols etc..
end
I'd like the GUI to close when I press the close button in the window, that's why I defined the following callback:
function assign_callbacks(obj)
%assign_callbacks Assigns the callbacks of the GUI
% Closing event
obj.gui_handles.figure.CloseRequestFcn = @(hObject,eventdata)close_figure_Callback(hObject,eventdata,obj);
%% --- Executes on close figure
function close_figure_Callback(~,~,obj)
delete(obj)
delete(gcf)
end
end
I start the GUI by:
%% Only start the app if it is not running yet
if exist('app_object','var') == 0
app_object = App();
else
clear app_object
app_object = App();
end
When I close the figure, the window closes and the GUI is cleared. However, the app_object is still existing in the base workspace, it is empty though. I'd like to clear the object from the base workspace. The reason for this is that I want to prevent my GUI from initializing twice by calling the start script.. Is this the right way to achieve this?

Respuestas (1)

function close_figure_Callback(~,~,obj)
delete(obj)
delete(gcf)
clear main_window_layout %get rid of the persistent
evalin('base', 'clear app_object;');
end

5 comentarios

Jan Loof
Jan Loof el 26 de Jun. de 2020
I think this can help to solve the problem but relies on the object instance being called 'app_object', what if it's called different?
Then you are going to have problems with your code that checks the existence of app_object .
If your question is, "How can an object know the name of the variable it was assigned to", the answer is, "It can't".
Value objects have a different name in every workspace they exist in, and might have several names in the same workspace, since they can be assigned to different variables.
You could whos() the base workspace and look for values listed as being of the correct datatype... but are you sure that the user even stored the object in the top level of a variable? And if it is a value object, can you be sure that you have found the right object?
Handle objects have a different name in every workspace they exist in, and might have several names in the same workspace, since they can be assigned to different variables. The difference is for handle objects, you can use isequal() to test whether the handle is the same as the handle of the object you are working with... if you can find the handle (are you sure it is even stored in the top level of a variable?)
I would suggest to you that rather than just checking the existance of the variable, that you also check isvalid() of the handle.
Jan Loof
Jan Loof el 26 de Jun. de 2020
Editada: Jan Loof el 26 de Jun. de 2020
How about this solution then:
function close_figure_Callback(~,~,obj)
delete(obj)
delete(gcf)
clear main_window_layout %get rid of the persistent
% Clean up base workspace
evalin('base','vars = whos()');
evalin('base','name = vars(strcmp({vars.class},''App'')).name');
evalin('base','clearvars(name)');
end
This searches for my class instances in the base workspace and clears them. In my case the user will always start the app in the base workspace and the goals is to have only one instance of the app open at all times.
I don't completely understand what you mean with the isvalid() of the handle and why it is necessary?
Edit: only clear name and not name{:} because name is a character.
%% Only start the app if it is not running yet
if ~exist('app_object','var') || ~isvalid(app_object)
app_object = App();
else
clear app_object
app_object = App();
end
Mind you, I do not understand why you clear app_object and start a new one if the existing one is still valid ??
Jan Loof
Jan Loof el 26 de Jun. de 2020
Because this re-initializes the app and adds default values to possibly already present values.

Iniciar sesión para comentar.

Categorías

Más información sobre Code Execution en Centro de ayuda y File Exchange.

Productos

Versión

R2018b

Etiquetas

Preguntada:

el 26 de Jun. de 2020

Comentada:

el 26 de Jun. de 2020

Community Treasure Hunt

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

Start Hunting!

Translated by