Output arguments in App Designer
71 ビュー (過去 30 日間)
古いコメントを表示
I would like to have functions that have some output parameters (and able to return these values to caller). Is it possible in App designer? I already checked the answers in community and got some work-around solution ideas.
I am currently using prerelease 2021a and this issue has been pending since 2016. Still don't have any `real` solution for it?
Thanks in advance.
Some edits regarding to Matt`s answer:
As the application whole, I want it to send some values back to me. So that, when the application window (aka. figure) is closed, those values are returned to me.
I'm waiting for this application figure to work like a dialog box.
Thanks Matt.
回答 (4 件)
Matt J
2021 年 1 月 2 日
[out1,out2]=app.func(in1,in2)
4 件のコメント
Walter Roberson
2021 年 1 月 3 日
In traditional figures, functions such as questdlg() work by creating graphics objects, setting up callbacks, and doing a waitfor() or uiwait(), extracting the data, deleting the graphics objects, and then returning the data.
One of the items I linked to suggested doing the same thing: running the app to create the graphics, doing a waitfor or uiwait, extracting the values, deleting the graphics objects, and then returning the data.
If that is not an acceptable solution for your situation, then you might have to wait a while for an acceptable solution to be implemented by Mathworks, as they do not provide any wrapper for that purpose in any released version.
Mario Malic
2021 年 1 月 3 日
編集済み: Mario Malic
2021 年 1 月 3 日
If you want to do this "As the application whole, I want it to send some values back to me. So that, when the application window (aka. figure) is closed, those values are returned to me. ", then you could write a CloseRequestFcn that will assign variables in the workspace (should you do it? No).
I would suggest you to create a function(as mentioned by Walter) that would create the uifigure (if the app is simple enough) because function can easily return values to workspace, here's my example on the File Exchange.
By the way, App Designer does not support output arguments, as mentioned by some of the staff in here.
Lior de Marcas
2021 年 11 月 16 日
I am a novice with App Designer, so if someone have any problems with anything I have written here, fill free to comment and help me learn :)
I recently came into the same problem - I wanted to create a small UI, that ask user to perform some task (multi-image labelling, while playing a video in order to help them). I wanted to use App Designer, as building UI programmatically only is a pain. Ideally, users can:
- Write their own functions that can used the UI produced labels.
- Run the UI from command window, and continue using cm if they want (non-modal window).
I found 2 possible solutions:
More general one: have the uifigure "CloseRequestFcn" save to mat file any output you want. Then you can wait for UI to close (when calling from function, use "waitfor"), and load this file. Pros: Easy to do, keep all of App Designer abilities. Saving any hard collected user input in not necessarily a bad idea. Cons: This is somewhat "poofing" variables into existence, similar to the option @Mario Malic did not recommend above. Also great way to save unneeded files (especially if you will save this output later, after more analysis). May be slow.
Less general: save wanted outputs as properties, then make sure your app object "live" after the uifigure was closed. However I found out that something in matlab.apps.AppBase class make sure the app object is deleted when its associated uifigure is closed, and I haven’t found simple workaround for that.
So I exported my app to .m file (one of the options under "save"), and changed it to be a "handle" class -
classdef my_UI < handle
inside the app Constructor remove the "registerApp", switch the function "runStartupFcn" with a simple call to your "startupFcn".In the createComponents function, any component callback switch from:
createCallbackFcn(app, @myCallBack, true);
To:
@(~,evt) myCallBack(app,evt)
More changes might be needed in case your app use more App Designer abilities that I'm not familiar with.
Pros: now your app is an object with graphic fields instead of being dependent on the figure (Why this dependency is needed anyway?). No need to save any variable - it is all in the class, no variable was "poofed" into later code. Cons: for more complex app may take a little longer (not very time consuming in any case I think). You may lose some of App Designer due to this change (I am not familiar with App Designer enough to say).
I think all in all, the first option in better, even if the secound is more "nice looking".
0 件のコメント
Walter
2025 年 6 月 14 日 13:58
Using uiwait and uiresume, a quite elegant solution, similar to how GUIDE used to do this, is possible as follows:
Suppose you want to create a dialog "testdialog" that returns a single value "result":
- Create a new blank app "testdialog".
- Define the output argument "result" as private property of testdialog.
- Define a StartupFcn for testdialog add a call to uiwait at its end; this will make the dialog wait until we have results.
- Define a CloseRequestFcn for app.UIFigure, replace the generated delete(app) in this function by uiresume(app.UIFigure).
- Inside the dialog class, if you want to return to the caller with result value, set the result property first, then call uiresume(app.UIFigure)
- Finally, add the following static function "invoke" to testdialog for invoking the dialog and returning the result:
function result = invoke()
app = testdialog(); % Invoke the dialog app
result = app.result; % Get result variable
delete(app); % Now delete the dialog
end
You invoke the dialog as follows:
result = testdialog.invoke()
The following complete example returns value 123 when you press a button. The dialog returns [] if the dialog is closed without pressing the button:
classdef testdialog < matlab.apps.AppBase
% Properties that correspond to app components
properties (Access = public)
UIFigure matlab.ui.Figure
ReadyButton matlab.ui.control.Button
end
properties (Access = private)
result % Dialog result variable
end
methods (Static = true)
% Static function for invoking a dialog and returning the result
function result = invoke()
app = testdialog(); % Create the dialog
result = app.result; % Return result variable
delete(app); % Close and delete the dialog
end
end
% Callbacks that handle component events
methods (Access = private)
% Code that executes after component creation
function startupFcn(app)
app.result = []; % Initially no result
uiwait(app.UIFigure); % Wait here until dialog finished
end
% Button pushed function: ReadyButton
function ReadyButtonPushed(app, event)
app.result = 123; % We want this result value
uiresume(app.UIFigure); % Resume the startupFcn
end
% Close request function: UIFigure
function UIFigureCloseRequest(app, event)
app.result = []; % Return no data if user closes the dialog
% DO NOT delete(app); % Keep the app object around for a while, it is needed by invoke!
uiresume(app.UIFigure); % Resume the startupFcn
end
end
% Component initialization
methods (Access = private)
% Create UIFigure and components
function createComponents(app)
% Create UIFigure and hide until all components are created
app.UIFigure = uifigure('Visible', 'off');
app.UIFigure.Position = [100 100 640 480];
app.UIFigure.Name = 'MATLAB App';
app.UIFigure.CloseRequestFcn = createCallbackFcn(app, @UIFigureCloseRequest, true);
% Create ReadyButton
app.ReadyButton = uibutton(app.UIFigure, 'push');
app.ReadyButton.ButtonPushedFcn = createCallbackFcn(app, @ReadyButtonPushed, true);
app.ReadyButton.Position = [271 92 100 23];
app.ReadyButton.Text = 'Ready!';
% Show the figure after all components are created
app.UIFigure.Visible = 'on';
end
end
% App creation and deletion
methods (Access = public)
% Construct app
function app = testdialog
% Create UIFigure and components
createComponents(app)
% Register the app with App Designer
registerApp(app, app.UIFigure)
% Execute the startup function
runStartupFcn(app, @startupFcn)
if nargout == 0
clear app
end
end
% Code that executes before app deletion
function delete(app)
% Delete UIFigure when app is deleted
delete(app.UIFigure)
end
end
end
0 件のコメント
参考
カテゴリ
Help Center および File Exchange で Creating, Deleting, and Querying Graphics Objects についてさらに検索
製品
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!