uiresume not working in function.

10 views (last 30 days)
Jeremy
Jeremy on 3 Mar 2023
Edited: Voss on 3 Mar 2023
I was updating an old GUIDE figure to the new format and cannot get a uiwait / uiresume to work inside the function. I can boil it down the function below, when I select this code and just run it the command line it works fine; if I run the function I get an error when I press continue:
Error using matlab.ui.Figure/get
Invalid or deleted object.
Error in uiresume (line 25)
if ~strcmp (get(hFigDlg, 'Type'), 'figure').
Code:
function [] = xxx()
fig = uifigure;
btn = uibutton(fig);
btn.Text = 'Continue';
btn.ButtonPushedFcn = 'uiresume(fig)';
disp('This text prints immediately');
uiwait(fig)
disp('This text prints after you click Continue');
close(fig);
end

Accepted Answer

Voss
Voss on 3 Mar 2023
Edited: Voss on 3 Mar 2023
Callbacks specified as character vectors (as in "'uiresume(fig)'") execute in the base workspace, so when the Continue button is pressed, the code will look for the variable fig in the base workspace. It may or may not exist, and if it exists it may or may not refer to the correct thing. For instance, I can see from the error you got ("Invalid or deleted object.") that fig referred to another figure that had already been deleted.
Instead of using a character vector callback, use a function, as in any of the following examples:
Example 1: using an anonymous function
function [] = xxx()
fig = uifigure;
btn = uibutton(fig);
btn.Text = 'Continue';
btn.ButtonPushedFcn = @(src,~)uiresume(ancestor(src,'figure'));
disp('This text prints immediately');
uiwait(fig)
disp('This text prints after you click Continue');
if ishandle(fig)
close(fig);
end
end
Example 2: using a nested function (this is the method I prefer)
function [] = xxx()
fig = uifigure;
btn = uibutton(fig);
btn.Text = 'Continue';
btn.ButtonPushedFcn = @cb_continue;
disp('This text prints immediately');
uiwait(fig)
disp('This text prints after you click Continue');
if ishandle(fig)
close(fig);
end
function cb_continue(~,~)
uiresume(fig);
end
end
Example 3: using a separate function (could be a sub-function of xxx as shown here, or could be a function in a separate m-file)
function [] = xxx()
fig = uifigure;
btn = uibutton(fig);
btn.Text = 'Continue';
btn.ButtonPushedFcn = {@cb_continue,fig};
disp('This text prints immediately');
uiwait(fig)
disp('This text prints after you click Continue');
if ishandle(fig)
close(fig);
end
end
function cb_continue(~,~,fig)
uiresume(fig);
end
I prefer to use nested functions because a nested function automatically has access to all variables in the nesting function's workspace (e.g., cb_continue has access to the variable fig in the function xxx's workspace). If a non-nested function needs access to numerous variables in the main function's workspace, you'd have to figure out how to give it access to what it needs, for example by passing all the variables as arguments to it. But if you use a nested function, you don't need to worry about that.
Also, note that in all cases I check ishandle(fig) before calling close(fig); that's done in case the user closed the figure without pressing the Continue button, in which case code execution resumes from the point of uiwait, but the figure has already been deleted, so you'd get an error trying to close a deleted figure.

More Answers (0)

Categories

Find more on Develop uifigure-Based Apps in Help Center and File Exchange

Products


Release

R2021b

Community Treasure Hunt

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

Start Hunting!