如何从appdesigner(Matlab)中的应用程序类外部访问数据 [英] How can I access data from outside the app class in appdesigner (Matlab)
问题描述
我在appdesigner(Matlab)中使用一个下拉菜单创建了一个非常简单的GUI.另外,我提取了生成的代码(在代码视图"选项卡下),并将其粘贴到普通的.m文件中(因为我想进一步向该代码添加更多内容).我的问题是如何从此自行生成的代码访问某些变量,以便可以在主类之外使用该值?
例如:
在App类中,对于此下拉菜单部分,已生成以下代码行:
app.ColorDropDown = uidropdown(app.UIFigure);app.ColorDropDown.Items = {'红色','蓝色','黄色'};app.ColorDropDown.Position = [277 178 140 22];app.ColorDropDown.Value ='红色';
此应用类的外部:根据我在此下拉菜单中选择的值,我想将其捕获到普通变量中,并根据选择的颜色显示其他结果>
谢谢
似乎您的问题的实质是关于在GUI之间共享数据,因为您声明要根据所选颜色显示其他结果".
注意:
详细信息
为简单起见,我将 controlGUI 设置为主要应用程序.我可以在controlGUI中添加一个名为 PlotWindow
的属性,并使其包含调用 plotGUI()
的输出;另一个mlapp.我还有一个回调函数,可用于三个下拉列表的回收,这些下拉列表用于更新plotGUI中的DATA属性.此DATA属性附加了一个侦听器,该侦听器将触发回调以更新 uiaxes
对象.
plotGUI
魔术确实存在于此物体中.也就是说,我创建了一个名为DATA的属性并更改了访问权限.通过设置属性访问权限 SetObservable = true
,我们可以添加一个 PostSet
事件侦听器,该侦听器在调用过程中存储在名为 dataChangedListener
的私有属性中. startupFcn
.
属性(访问权限=公共,SetObservable = true)DATA%具有xdata,ydata,字段的结构.其他行道具场还可以结尾属性(访问权限=私有)更改DATA时的dataChangedListener%侦听器对象.结尾
然后,启动函数 startupFcn
使用struct then 添加的(任意)数据初始化DATA属性,然后添加并启用 PostSet
侦听器
%在组件创建后执行的代码函数startupFcn(app,data)如果nargin<2个%创建一个默认数据集数据= struct();数据.xdata = linspace(0,1,1001);data.ydata = sin(data.xdata.* 2 * pi * 10);%10hz信号data.color = app.Axes.ColorOrder(1,:);结尾app.DATA =数据;%绘制数据行(数据,``父级'',app.Axes);%为DATA属性添加并启用PostSet事件侦听器app.dataChangedListener = addlistener(...app,'DATA','PostSet',...@(s,e) app.updatePlot ...);app.dataChangedListener.Enabled = true;结尾
PostSet
侦听器调用方法 app.updatePlot()
,因此我们必须将此方法添加到我们的应用程序中.每当 app.DATA
中的任何内容被修改时,该方法都会被称为.因此,我创建了功能"(如代码浏览器所称),该功能仅删除了 axes
子代(现有行)并使用了 low-level 版本> line()
来绘制基于 app.DATA
结构对象的原始行:
函数updatePlot(app)清除图的百分比delete(app.Axes.Children);%绘制新图line(app.DATA,'parent',app.Axes);结尾
是的, line()
将接受一个结构,该结构的字段名称与有效的行属性相对应,但我似乎找不到专门的引用.但是,如果您阅读了 inputParser对象 ...抱歉,下车话题.
controlGUI
此对象更简单.它将plotGUI保留在一个属性中,从而可以直接访问plotGUI属性和公共方法.
属性(访问权限=公共)PlotWindow = plotGUI()%保存对绘图窗口的引用结尾
我在这里还创建了一个 updatePlot
回调方法,与plotGUI方法不同,我的名字不好.但是,此控制方法从controlGUI下拉列表中获取值,然后修改存储在 app.PlotWindow.DATA
中的plotGUI DATA
结构.因此,只要更改任何下拉列表( ValueChangedFcn
),就会调用此回调.因此, DATA
结构的 PostSet
侦听器将触发回调以相应地更新绘图.
%值更改功能:LineColor,LineStyle,MarkerStyle函数updatePlot(app,event)mStyle = app.MarkerStyle.Value;lStyle = app.LineStyle.Value;lColor = app.LineColor.Value;d = app.PlotWindow.DATA;开关mStyle案件无"d.marker ='none';案例圆"d.marker ='o';案例钻石"d.marker ='钻石';案例点"d.marker ='.';结尾开关lStyle案件无"d.linestyle ='none';案例坚实"d.linestyle ='-';案例破折号"d.linestyle ='-';案例点缀"d.linestyle =':';结尾d.color = lColor;%将数据设置回plotGUI%plotGUI的DATA PostSet侦听器将更新实际图app.PlotWindow.DATA = d;结尾
I have created a very simple GUI in appdesigner (Matlab) with one dropdown menu. Additionally, I took the code that got generated (under 'Code View' tab) and pasted that in a normal .m file (because, I want to further add some more contents to this code). My question is how can I access certain variable from this self generated code, so that I can play with that value outside of the main class?
For example:
In App class, for this dropdown menu section, following line of code got generated:
app.ColorDropDown = uidropdown(app.UIFigure);
app.ColorDropDown.Items = {'Red', 'Blue', 'Yellow'};
app.ColorDropDown.Position = [277 178 140 22];
app.ColorDropDown.Value = 'Red';
Outside of this app class: Depending upon the value that was selected in this dropdown menu, I want to capture that in a normal variable, and show some other results based on the color selected
Thanks
It seems like the essence of your question is about sharing data between GUIs as you state you want to "show some other results based on the color selected".
Note: MATLAB documentation cautions: Do not use UserData
property in apps you create with App Designer.
The documentation goes on to recommend approaches for sharing data among app designer apps and creating multiwindow apps in app designer.
For the sake of completeness, I'll provide a detailed example, different from the MATLAB documentation, of how this can be accomplished entirely within the App Designer.
Setup
I created 2 app designer apps, controlGUI.mlapp and plotGUI.mlapp. Running controlGUI()
loads both mlapp files at once and then allows you to control aspects of the plotGUI from callbacks in the controlGUI. Of course, the plotGUI could do anything but I have it changing visual aspects of the plotted data.
Details
For simplicity, I am setting the controlGUI be the main application. I can do this be adding a property in controlGUI named PlotWindow
and having it contain the output of calling plotGUI()
; the other mlapp. I also have a callback function I recycle for the three dropdowns that updates a DATA property in the plotGUI. This DATA property has a listener attached that fires a callback to update the uiaxes
object.
The plotGUI
The magic is really in this object. That is, I created a property named DATA and altered the access. By setting the property access SetObservable = true
, we can then add a PostSet
event listener, which I stored in a private property called dataChangedListener
during the startupFcn
.
properties (Access = public, SetObservable=true)
DATA % A struct with xdata, ydata, fields. Other line prop fields ok
end
properties (Access = private)
dataChangedListener % listener object for when DATA is changed.
end
Then the startup function, startupFcn
, initializes the DATA property with some (arbitrary) data as struct then adds and enables the PostSet
listener.
% Code that executes after component creation
function startupFcn(app, data)
if nargin < 2
% create a default dataset
data = struct();
data.xdata = linspace(0,1,1001);
data.ydata = sin(data.xdata.*2*pi*10);%10hz signal
data.color = app.Axes.ColorOrder(1,:);
end
app.DATA = data;
% plot the data
line(data, 'parent', app.Axes);
% add and enable PostSet event listener for the DATA property
app.dataChangedListener = addlistener(...
app,'DATA','PostSet', ...
@(s,e) app.updatePlot ...
);
app.dataChangedListener.Enabled = true;
end
The PostSet
listener calls the method app.updatePlot()
, so we have to add this method to our app. This method will get called whenever anything in app.DATA
gets modified. So I created the "function" (as the Code Browser calls it) which simply deletes the axes
children (the existing line) and uses the low-level version of line()
to draw a primitive line based on the app.DATA
struct object:
function updatePlot(app)
%clear plot
delete(app.Axes.Children);
% draw the new plot
line(app.DATA, 'parent', app.Axes);
end
Yes, line()
will accept a struct which has field names that correspond to valid line properties but I can't seem to find the reference specifically. But if you read about the inputParser object... sorry, getting off topic.
The controlGUI
This object is simpler. It holds the plotGUI in a property, allowing direct access to the plotGUI properties and public methods.
properties (Access = public)
PlotWindow = plotGUI() % holds the reference to the plot window
end
I also created an updatePlot
callback method here, different from the plotGUI method, bad naming on my part. Nonetheless, this control method takes the values from controlGUI dropdowns and then modifies the plotGUI DATA
struct, stored in app.PlotWindow.DATA
. So this one callback is called whenever any of the dropdowns are changed (ValueChangedFcn
). Consequently, the PostSet
listener for the DATA
struct will fire the callback to update the plot accordingly.
% Value changed function: LineColor, LineStyle, MarkerStyle
function updatePlot(app, event)
mStyle= app.MarkerStyle.Value;
lStyle= app.LineStyle.Value;
lColor = app.LineColor.Value;
d = app.PlotWindow.DATA;
switch mStyle
case 'none'
d.marker = 'none';
case 'circle'
d.marker = 'o';
case 'diamond'
d.marker = 'diamond';
case 'point'
d.marker = '.';
end
switch lStyle
case 'none'
d.linestyle = 'none';
case 'solid'
d.linestyle = '-';
case 'dashed'
d.linestyle = '--';
case 'dotted'
d.linestyle = ':';
end
d.color = lColor;
% set the data back into the plotGUI
% The plotGUI's DATA PostSet listener will update the actual plot
app.PlotWindow.DATA = d;
end
这篇关于如何从appdesigner(Matlab)中的应用程序类外部访问数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!