如何从appdesigner(Matlab)中的应用程序类外部访问数据 [英] How can I access data from outside the app class in appdesigner (Matlab)

查看:89
本文介绍了如何从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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆