Call an MLAPP with input argument(s)

Typically, in a classdef, you define input arguments in the class constructor. Within appdesigner, the class constructor is written automatically, and is locked out to prevent problems.
Has anybody found a different way to pass input arguments to an appdesigner MLAPP?
EDIT: This has been resolved with R2017b. For releases prior to R2017b, the accepted answer by Chris Portal is still the best workaround.

 Accepted Answer

A workaround for now is to create a public function in your app (use the "+ Function" in Code View and choose the "public" option) and use that to pass in any "input variables" after the app is created. For example:
hApp = myapp;
MySetupFunction(hApp, input1, input2);
It's not the proper way, but it's the closest way of working around the limitation for now.

8 Comments

I checked the "email me answers are added" option, and never got an email...
This answer is better than the 2 I expected ("use globals!" and "why not evalin('base',...)?"). My initial hesitation is that this won't work if the inputs are necessary before any of the startupFcn code executes.
Thanks for the suggestion!
Hi Chris, May you please elaborate on this answer. I am new to App Designer and am having problems integrating this into my code. Thanks.
This would often take the form of what is known as 2nd phase initialisation. You create your app without the inputs, then you just create another public function that allows you to pass in the things you would normally have passed into the constructor.
It has the disadvantage that the app exists in what may be considered an 'uninitialised' state if you forget to call this function, but if you always pair up the call to create the app and the call to the initialise/setup function then it fulfils the role at least.
Thanks Adam. Do you know if there is a way of passing an input variable (such as a listbox selection) from one mlapp into another mlapp?
I have a listbox in mlappA and once a button is pressed it opens a new mlappB file. I would like to use the listbox selection from mlappA in the new mlappB file. Thanks!
In the button callback you should be able to just create your 2nd app and then set your listbox selection on it and do with it what you please e.g.
function SomeButtonCallback( mlappA, event)
hAppB = mlappB;
hAppB.setSelection( mlappA.someListbox.Value )
end
for example. Obviously if you want the string you'd have to get that from the listbox and index into it with the value to get the selection.
Hi Adam, I got the error No appropriate method, property, or field 'setSelection' for class 'matlab.ui.control.ListBox'.
But I finally figured it out also using the function SomeButtonCallback( mlappA, event)
hAppB = mlappB;
hAppB.someListbox.Value=hAppA.firstlistbox.Value
This initialized my listbox in my second file with the value from my first file.
Thanks so much for your help!!
Yes, my 'setSelection' was just a place holder for whatever function you chose to add on your second app to set the selection. The expectation was you would create that as a function (with your chosen name) and then put relevant code inside it.
Thanks, that makes sense. I'm fairly new to Matlab and especially App Designer so thanks for your patience, I appreciate the help!

Sign in to comment.

More Answers (5)

In R2017b, App Designer supports input arguments for apps. From the Run button in the toolstrip, select the drop down and select "Add Input Arguments. Add the variable names you wish to use. App Designer will automatically create a startup function for you if one does not exist, and update the constructor correctly. Write the code needed to process the input arguments in your startup function.

1 Comment

I voted for you answer, but I'd like to leave the original "Accepted Answer" for those not fortunate enough to have R2017b. That way, they can still see the workaround.

Sign in to comment.

Adam
Adam on 16 Dec 2016
Edited: Adam on 19 Dec 2016
This is certainly an unpleasant limitation. This is my first foray into appdesigner after being very familiar with creating programmatic GUIs using classes. The uneditable constructor and component initialisation functions will certainly take me some getting used to. In GUIDE I am used to passing input arguments in and using them to initialise sliders etc within the OpeningFcn.
My solution to the problem of not being able to pass input arguments to the constructor will likely be to create a 'named constructor' as a public static function, e.g.
methods ( Static, Access = public )
function app = create( someStuff, someOtherStuff )
app = MyApp;
app.someStuff = someStuff;
initialiseSlider( app, someOtherStuff );
end
end
and then launch the app as e.g.
MyApp.create( 7, 15 );
It still means that the app is created before you can assign any of your properties or setup slider components based on inputs, but hopefully that will not represent a problem.
I hope appdesigner evolves to allow more standard class usage though. I understand why some of the code is locked to stop people screwing up the app by adding code that doesn't make sense, but for people who know what they are doing it is frustrating to have to use workarounds in code design.
Annoyingly the 'coding alerts' equivalent of M-Lint are very simplistic too. I get an alert saying I should use 'app' as the first argument to this create function even though it is in a Static methods block!
You can provide inputs through a subclass. If the app you created with AppDesigner is called myApp then create a subclass (not in AppDesigner, in an ordinary editor)
classdef myActualApp < myApp
methods % define the constructor
function mAA = myActualApp(inputs ...)
mAA = mAA@myApp; % this line is not really necessary
....
process inputs
...
end
end
end
As far as I know you can't in the official editor You can probably with an external editor...not sure what happens then though if open the file again in the official editor
But, may be you can insert a function to change the data members and call it using callback function.
Hello, The app designer editor is locked. But you can copy-paste all the code from the mlapp in a classic .m file and run it like usual.
After this you can pass arguments through the constructor and the output method of the app class.
But if you still want to edit the GUI with the design view you cannot re-copy-paste the code inside the mlapp. So do the trick only when your GUI is close to be finish.

Categories

Products

Asked:

on 13 May 2016

Commented:

on 16 Oct 2017

Community Treasure Hunt

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

Start Hunting!