App Designer: Using function outputs as variables within other functions
显示 更早的评论
I would like to store a variable as an output from a function in App Designer for use with other functions. Please see the simple example below.
properties (Access = private)
x = linspace(0,1,10); % Description
end
methods (Access = private)
function [y] = func(app)
A = app.EditField.Value;
B = A + 1;
y = app.x.^2 + B;
plot(app.UIAxes,app.x,y)
end
I wish to use the variable 'y' from func(app) for use within the second function, func2(app).
func2(app)
plot(app.UIAxes2,app.x,y)
end
end
Any help would be appreciated, the example is trivial as both plots plot the same graph. I am just unaware of the syntax required as the App Designer environment has slight modifications from that of the usual MATLAB workspace.
Any help would be very appreciated,
Sam
(Using R2017b)
采纳的回答
更多回答(1 个)
Mark Eigenraam
2022-4-11
1 个投票
As a follow on, I had a similar problem. if I run the following a = myapp (pass_in_data), after the user has made changes to pass_in_data, how do i send the updated data back to the mlapp that called myapp. Thanks
6 个评论
Walter Roberson
2022-4-11
Create a wrapper level for myapp that invokes myapp and records the handle returned. Then have that wrapper waitfor() https://www.mathworks.com/help/matlab/ref/waitfor.html#mw_e1d55a0f-ac45-439f-b2e1-5075607083fb something about myapp. It should then fetch some property of myapp, and then either destroy myapp or make it invisible. Then return that appropriate value from the wrapper.
Mark Eigenraam
2022-4-11
thanks a lot. Seems a bit messy. In the past you could call the handles from another fig.
handles = guidata(handles.fig_main);
now with mlapp this all seems very hard! Or perhaps I am missing something.
Walter Roberson
2022-4-13
apps are objects that are derived from a class that is a handle class.
In the normal course of events, when the other program invoked myapp, that would be a constructor call and after the constructor finished executing, the app handle object would be returned from the call to myapp .
What happens after that depends upon how you defined the properties of the object. If you defined them as public properties without a get/set method, then the other code could do standard ObjectName.PropertyName references. Any changes after that to the object properties inside the myapp implementation, would be immediately available to the calling routine that knew to ask for the right property name. It would not be uncommon to construct a public get method for the property without a corresponding public set method, to prevent the outside function from changing the internal properties of myapp .
However... it would not be reasonable to say that those properties are the output of myapp . myapp can only return one thing, and that is the handle of the myapp object.
The older system such as GUIDE, dealt with all of this by allowing the programmer to put a waitfor() at the end of its main function, at which time it would look inside the handles to find a particular property, and would return the value of that property instead of returning the handle to the figure() as would normally be the case if you did not use that mechanism.
Something similar is not an option for constructors of handle objects: constructors of handle objects must return the handle to the object.
This leads to my suggestion of having another layer that constructs the object, waitfor() some event, fetches an appropriate property, and returns it.
You could probably make that wrapper layer a static method of the class. However, if the class has not yet been loaded, then the methods for the class have not been loaded, and so are not on the seach path, so you would not be able to reliably invoke the wrapper static method just by name. The work-around for that would be to invoke
output = myapp.StaticMethodNameThatDoesTheWrapping
You should, however, be thinking in terms of the same design principles as with GUIDE, in the sense of thinking that GUIs do not have "output" (in the sense of returned values) as long as they are live, that if you want "output" from a GUI, you have to do the equivalent of invoking the GUI and having it wait to terminate and return the value instead of the handle to the GUI. (It is not strictly necessary to destroy the GUI in such a case.
Having a function / method that returns the current value of a property of a live GUI is a different matter entirely than expecting the GUI itself to have output.
Mark Eigenraam
2022-4-13
thanks a lot, very helpful. I have also used the following as guidance, note the guidance has some issues, but they can be figured out. the key lines of code that can be modified are the following. I can now pass data from Appdesign GUI to Appdesign GUI readily.
updateplot(app.CallingApp, app.EditField.Value, app.DropDown.Value);
app.CallingApp.OptionsButton.Enable = 'on';
You can look at this example:
In MATLAB, type:
>> openExample('matlab/TopLevelMultiwindowAppExample','supportingFile','DialogAppExample');appdesigner('MainAppExample');
Walter Roberson
2022-4-13
That example works by having the calling program provide an update method that the called app is responsible for invoking in order to export changes. That is certainly a valid thing to do, but it is not the same as saying that your app has "output".
You asked "how do i send the updated data back to the mlapp that called myapp" and the example you are looking at does not do that: instead it tells the calling app to update itself. Different dynamic.
Mark Eigenraam
2022-4-13
Yes you are correct. I have written code (based on the Mathworks example) in the calling app now that updates its data, without closing the child app. I could have used better phrasing :)
类别
在 帮助中心 和 File Exchange 中查找有关 Data Type Identification 的更多信息
产品
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!