uiresume not working in function.

2 Ansichten (letzte 30 Tage)
Jeremy
Jeremy am 3 Mär. 2023
Bearbeitet: Voss am 3 Mär. 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

Akzeptierte Antwort

Voss
Voss am 3 Mär. 2023
Bearbeitet: Voss am 3 Mär. 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.

Weitere Antworten (0)

Kategorien

Mehr zu Develop uifigure-Based Apps finden Sie in Help Center und File Exchange

Produkte


Version

R2021b

Community Treasure Hunt

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

Start Hunting!

Translated by