0

我用一个下拉菜单在 appdesigner (Matlab) 中创建了一个非常简单的 GUI。此外,我获取了生成的代码(在“代码视图”选项卡下)并将其粘贴到一个普通的 .m 文件中(因为我想进一步向该代码添加更多内容)。我的问题是如何从这个自我生成的代码中访问某些变量,以便我可以在主类之外使用该值?

例如:

在 App 类中,对于这个下拉菜单部分,生成了以下代码行:

app.ColorDropDown = uidropdown(app.UIFigure);
app.ColorDropDown.Items = {'Red', 'Blue', 'Yellow'};
app.ColorDropDown.Position = [277 178 140 22];
app.ColorDropDown.Value = 'Red';

在这个应用程序类之外:根据在这个下拉菜单中选择的值,我想在一个普通变量中捕获它,并根据选择的颜色显示一些其他结果

谢谢

4

2 回答 2

6

您的问题的本质似乎是关于在 GUI 之间共享数据,因为您声明要“根据所选颜色显示一些其他结果”。

注意:MATLAB 文档注意事项 请勿UserData在您使用 App Designer 创建的 App 中使用属性

该文档继续推荐在应用程序设计器应用程序之间共享数据和在应用程序设计中创建多窗口应用程序的方法。

为了完整起见,我将提供一个与 MATLAB 文档不同的详细示例,说明如何完全在 App 设计器中完成此操作。

设置

我创建了 2 个应用程序设计器应用程序controlGUI.mlappplotGUI.mlapp。运行controlGUI()一次加载两个 mlapp 文件,然后允许您从 controlGUI 中的回调控制 plotGUI 的各个方面。当然,plotGUI 可以做任何事情,但我让它改变了绘制数据的视觉方面。

在此处输入图像描述

细节

为简单起见,我将 controlGUI 设置为主应用程序。我可以通过在 controlGUI 中添加一个名为的属性PlotWindow并让它包含调用的输出plotGUI();另一个mlapp。我还有一个回调函数,用于更新 plotGUI 中的 DATA 属性的三个下拉列表。此 DATA 属性附加了一个侦听器,该侦听器触发回调以更新uiaxes对象。

plotGUI

魔法真的在这个物体上。也就是说,我创建了一个名为 DATA 的属性并更改了访问权限。通过设置属性 access SetObservable = true,我们可以添加一个PostSet事件监听器,我将它存储在一个私有属性dataChangedListener中,在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

然后启动函数,startupFcn用一些(任意)数据作为结构初始化 DATA 属性,然后添加并启用PostSet侦听器。

% 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

侦听器PostSet调用方法app.updatePlot(),所以我们必须将此方法添加到我们的应用程序中。每当修改中的任何内容时,app.DATA都会调用此方法。因此,我创建了“函数”(正如代码浏览器所称),它只是删除axes子项(现有行)并使用低级版本基于struct 对象line()绘制原始线:app.DATA

function updatePlot(app)
        %clear plot
        delete(app.Axes.Children);
        % draw the new plot
        line(app.DATA, 'parent', app.Axes);
    end

是的,line()将接受具有与有效行属性相对应的字段名称的结构,但我似乎无法具体找到参考。但是,如果您阅读了有关inputParser 对象的信息……抱歉,题外话。

控制GUI

这个对象比较简单。它将 plotGUI 保存在一个属性中,允许直接访问 plotGUI 属性和公共方法。

properties (Access = public)
    PlotWindow = plotGUI() % holds the reference to the plot window
end

我还在updatePlot这里创建了一个回调方法,与 plotGUI 方法不同,我的命名不好。尽管如此,这种控制方法从 controlGUI 下拉列表中获取值,然后修改 plotGUIDATA结构,存储在app.PlotWindow.DATA. 因此,只要更改任何下拉列表(ValueChangedFcn),就会调用这个回调。因此,结构的PostSet侦听器DATA将触发回调以相应地更新绘图。

% 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
于 2018-08-29T19:22:40.427 回答
1

您不应该使用 App Designer 在代码编辑器之外复制/粘贴代码。如果您想添加自己的代码,您应该使用 App Designer 中的“功能”按钮向您的类添加一个新功能。该应用程序还可以调用任何其他 matlab 函数,因此您可以通过在 App Designer 代码中调用它来将信息从应用程序传递到另一个函数

例如,从我创建的演示中查看此示例。它使用下拉菜单ChartTypeDropDown来确定应该绘制哪种类型的图表。我添加了一个新的function调用DrawChart,它使用来自 GUI 的数据根据​​选择/输入到各个框中的值绘制图表。

    function results = DrawChart(app)
        chartType = app.ChartTypeDropDown.Value;
        chartTime = app.TimeEditField.Value;
        chartA = app.AEditField.Value;
        chartB = app.BEditField.Value;
        chartC = app.CEditField.Value;
        t = [0:0.1:chartTime];
        if strcmp(chartType,'Sin')
            y = chartA * sin(chartB*t)+chartC;
        elseif strcmp(chartType,'Cos')
            y = chartA * cos(chartB*t)+chartC;
        elseif strcmp(chartType,'Exp')
            y = exp(t);
        else
            y = x;
        end
        ax = app.UIAxes;
        ax.Title.String = chartType;
        plot(ax,t,y);
    end

此函数由链接到按钮的回调调用

    function DrawButtonPushed(app, event)
        DrawChart(app);
    end

请注意我如何调用常规的 matlab 函数,例如 sin/cos/exp。这些可以很容易地成为您编写的 Matlab 函数。

于 2018-08-09T16:09:50.833 回答