【问题标题】:how to implement the idea of mvc design in matlab gui's如何在matlab gui中实现mvc设计的思想
【发布时间】:2011-03-30 06:17:41
【问题描述】:

请我是一名学生,该项目正在开发一个可视化工具,以使用 matlab 中的 mvc 设计来分析数据。但我遇到的问题是我对编程很陌生,而 matlab 是我第一个真正的编程。我几乎完成了代码,但我担心它们在 mvc 设计模式中是不可能的,所以我需要改变它。

非常感谢尽可能多的估算,以便将我与有用的材料联系起来,因为我在 matlab 中找不到任何 mvc 或可能是在 matlab 中实现 mvc 的示例代码,以帮助我了解如何做我的,目前正在做这样的事情,其中​​数据是一个带有.Name和.Data文件的结构。函数/方法 datcorrCoef 和 datCorrSum 是我创建的函数,它们接受我的数据对象作为参数


function dataAnalysisGUI(data)

fdataAnalysisGUI = figure('Name','Data Analysis ',...
    'tag','dataAnalysisGUI',...
    'menu','none',...
    'units','normalized',...
    'NumberTitle', 'off')



%%% intialise the gui with data set to work with
vtDaUD.opD = data;



Rsq = datcorrCoef(vtDaUD.opD);
opit = datWrappa(Rsq);
vtDaUD.wd = opit;
vtDaUD.feel = datCorrSum(data);
%%%------------------- menus ------------------------------------------%%%
smh = uimenu('Label', 'Sort', 'Tag', 'daSortMenu');
cmh = uimenu(smh, 'Label', 'Sum of CorrCoeff ',...
    'Tag', 'correlation');
    uimenu(cmh, 'Label', 'Increasing ',...
    'Tag', 'cIncreasing',...
    'callback','vtDaCallbacks(''cIncreasing_callback'')');
    uimenu(cmh, 'Label', 'Decreasing ',...
    'Tag', 'cDecreasing',...
    'callback','vtDaCallbacks(''cDecreasing_callback'')');
mmh = uimenu(smh, 'Label', 'Max Lag ',...
    'Tag', 'maxLag');
    uimenu(mmh, 'Label', 'Increasing ',...
    'Tag', 'mIncreasing',...
    'callback','vtDaCallbacks(''mIncreasing_callback'')');
    uimenu(mmh, 'Label', 'Decreasing ',...
    'Tag', 'mDecreasing',...
    'callback','vtDaCallbacks(''mDecreasing_callback'')');



dmh = uimenu('Label', 'Display', 'Tag', 'daDisplayMenu');
            uimenu(dmh, 'Label', 'Scatter Plots ',...
                  'Tag', 'dScatter',...
                  'Callback','vtDaCallbacks(''dScatter_callback'')');
              uimenu(dmh, 'Label', 'Cross Correlation ',...
                  'Tag', 'dCrosscorr',...
                  'callback','vtDaCallbacks(''dCrosscorr_callback'')');
              uimenu(dmh, 'Label', 'Time Series ',...
                  'Tag', 'dTimeseries',...
                  'callback','vtDaCallbacks(''dTimeseries_callback'')');


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%------------------------ panels ------------------------------------%%%
 vtDaPanel1 = uipanel(fdataAnalysisGUI,...
       'Units','normalized',...
       'Position', [.025 .035 .84 .95],...
       'FontSize',10,...
       'tag','vtDaPanel1',...
       'backgroundcolor',[0.8, 0.8,0.8],...
       'title', 'Table of Cross Correlations between Data');
    vtDaPanel2 = uipanel(fdataAnalysisGUI,...
       'Units','normalized',...
       'Position', [.87 .566 .12 .396],...
       'tag','vtDaPanel2',...
       'backgroundcolor',[0.8, 0.8,0.8],...
       'title', 'Analysis');

   %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   %%%------------------------- objects -------------------------------%%%
        uitable('parent', vtDaPanel1,...
            'tag','vtDaTable',...
            'RearrangeableColumn', 'on',...
            'clipping','off',...
            'Units','normalized',...
            'Position',[.01 .2 .98 .8],...
            'data',opit.Data,...
            'rowname',opit.Name,...
            'columnname',opit.Name,...
            'CellSelectionCallback',{@daTable_callback,vtDaUD.opD});

        uitable('parent', vtDaPanel1,...
            'tag','vtDaTable2',...
            'RearrangeableColumn', 'on',...
            'Units','normalized',...
            'Position',[.01 .01 .98 .15],...
            'data',vtDaUD.feel.Data,...
            'rowname','Sum of Corr. Coeff',...
            'columnname',vtDaUD.feel.Name,...
            'TooltipString','select column header to drill down',...
            'CellSelectionCallback',{@daTable2_callback,vtDaUD.opD});


        uicontrol(vtDaPanel2, 'Style', 'popupmenu',...
            'tag','taskpopMenu',...
            'Units','normalized',...
            'Position', [.10 .75 .8 .1],...
            'String', {'Correlation Coeff';'Max lags'},...
            'Callback', 'vtDaCallbacks(''taskpopMenu_callback'')');

        uicontrol(vtDaPanel2, 'Style', 'text',...
            'tag','staticTxt2',...
            'Units','normalized',...
            'Position', [.10 .86 .8 .05],...
            'String', {'Task'});

        uicontrol(vtDaPanel2, 'Style', 'text',...
            'tag','staticTxt3',...
            'Units','normalized',...
            'Position', [.10 .61 .8 .05],...
            'String', {'Mini Display'});

        uicontrol(vtDaPanel2, 'Style', 'pushbutton',...
            'tag','pushTimeseries',...
            'Units','normalized',...
            'Position', [.10 .5 .8 .1],...%[450 350 100 50]
            'String', {'TimeSeries'},...
            'Callback', 'vtDaCallbacks(''pushTimeseries_callback'')');

        uicontrol(vtDaPanel2, 'Style', 'pushbutton',...
            'tag','pushScatter',...
            'Units','normalized',...
            'Position', [.10 .35 .8 .1],...
            'String', {'Scatter'},...
            'Callback', 'vtDaCallbacks(''pushScatter_callback'')');

        uicontrol(vtDaPanel2, 'Style', 'pushbutton',...
            'tag','pushMaxlag',...
            'Units','normalized',...
            'Position', [.10 .2 .8 .1],...
            'String', {'Max Lag'},...
            'Callback', 'vtDaCallbacks(''pushMaxlag_callback'')');


name = genvarname(['daGUI' data.Name{2}]);%name = datname('daGUI',lenght(data.Name));
vtDaUD.varName = name;
eval([name '= data.Data']);
assignin('base',name,data.Data);


set(fdataAnalysisGUI,'UserData',vtDaUD)

我已经完成了如下回调/控制;

function vtDaCallbacks(action)
handles = guihandles(gcf);
vtDaUD = get(handles.dataAnalysisGUI,'UserData');
%tabdata=get(handles.vtDaTable,'data');
tab2Data.Data = get(handles.vtDaTable2,'data');
tab2Data.Name = get(handles.vtDaTable2,'columnname');


switch action
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    %%%-----------------------Data AnalysisGUI menu callbacks-----------%%%
    case 'cIncreasing_callback'
        [newTabData,index] = sortaColumn(tab2Data,'ascend',1);
        vtDaUD.wd = dataselect(vtDaUD.opD,index);
        set(handles.vtDaTable2, 'data', newTabData.Data)
        set(handles.vtDaTable2, 'columnname', newTabData.Name)
        set(handles.vtDaTable2,'CellSelectionCallback',{@daTable2_callback,vtDaUD.wd});


    case 'cDecreasing_callback'
        [newTabData,index] = sortaColumn(tab2Data,'descend',1);
        vtDaUD.wd = dataselect(vtDaUD.opD,index);
        %[vtDaUD.wd,newTabData,newcolumnname] = sortta2(vtDaUD.opD,'descend',tab2Data,1);
        set(handles.vtDaTable2, 'data', newTabData.Data)
        set(handles.vtDaTable2, 'columnname', newTabData.Name)
        set(handles.vtDaTable2,'CellSelectionCallback',{@daTable2_callback,vtDaUD.wd});

    case 'dScatter_callback'
        dataDispGUI('dScatta','calnumpage2',vtDaUD.opD, 'Scatter Plots')

    case 'dTimeseries_callback'
        dataDispGUI('dTimeSeries2','calnumpage2',vtDaUD.opD, 'Time Series Plots')

    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    %%%-------------------Data AnalysisGUI uiobject callbacks-----------%%%

    case 'dataTable_callback'
        [indices,data1,data2] = daTable_callback(vtDa.opD);
        vtDaUD.data1=data1;
        vtDaUD.data2=data2;
        dsingTseries(y1,y2)

    case 'taskpopMenu_callback'
        val = get (handles.taskpopMenu,'value');
        switch val
            case 1
                Rsq = datcorrCoef(vtDaUD.opD);
                tab1data = datWrappa(Rsq);%vtDaUD.wd
                set(handles.vtDaPanel1,...
                    'title', 'Table of Cross Correlations between Data');
            case 2
                [maxT,lags,coeff]= datCrossCorr(vtDaUD.opD,30);
                tab1data = datWrappa(maxT);%vtDaUD.wd
                set(handles.vtDaPanel1,...
                    'title', 'Table of Max Lag between Data');
        end
        set(handles.vtDaTable, 'data', tab1data.Data)%vtDaUD.wd.Data
        set(handles.vtDaTable2,'data', vtDaUD.feel.Data)
        set(handles.vtDaTable2,'columnname', vtDaUD.feel.Name)
        set(handles.vtDaTable2,'CellSelectionCallback',{@daTable2_callback,vtDaUD.opD});



    case 'pushTimeseries_callback'
        dsingTseries(vtDaUD.opD,vtDaUD.varName,vtDaUD.indices)

    case 'pushScatter_callback'
        dsingScatta(vtDaUD.opD,vtDaUD.varName,vtDaUD.indices)

    case 'pushMaxlag_callback'
        dsingMlags(vtDaUD.opD,vtDaUD.varName,vtDaUD.indices)


end
set(handles.dataAnalysisGUI,'UserData',vtDaUD)

我再次在控制器中使用我的数据对象进行操作的其他功能;真的对整件事感到沮丧!如果我对我的问题的描述不够清楚,请告诉我,以便您提供帮助。谢谢

【问题讨论】:

  • 当您完成项目后,请告诉我们您的讲师针对 MATLAB 中的 MVC 使用了哪些编程模式/技术!

标签: model-view-controller design-patterns matlab


【解决方案1】:

你正在尝试的是一件不平凡的事情。 MATLAB 的 UI 系统 GUIDE 并没有那么灵活。我讨厌对此持否定态度。我感谢您尝试按照某种模式开发 UI,但我会简单地使用 GUIDE 并保留自动生成的代码段。

使用 Java 或 C# 作为 UI,然后使用 MATLAB Builder NEMATLAB Builder Java 引入 MATLAB 进行繁重的处理是一个更好的选择。我不确定学生版是否附带,但这确实是您想要的。

任何程序员都会学到的最重要的一课是每种语言都有优点和缺点。试图将一种语言强加为一种并非设计用于使用的范式是一场山上的战斗,通常会以更多的哭泣而不是欣喜而告终。

【讨论】:

    【解决方案2】:

    对于 MVC,您需要正确的面向对象。 MATLAB 中的 OO 在较新的版本中可用,您可以像在 Java 中执行 MVC 一样进行操作。但它在 MATLAB 中并没有“感觉”正确(所以我认为你的导师不是这个意思),因为在大多数简单的情况下以及对于复杂/大型 UI 的 MATLAB is too slow and has performance issues in some scenarios.

    否则,您可以使用嵌套函数(CS 中的闭包)。使用闭包可以“模拟”一些 OO 功能。唯一的问题是所有内容都必须保存在一个 m 文件中。

    • 模型:嵌套范围变量(此处命名为“this”)
    • 视图:uicontrols(和其他 ui 元素)
    • 控制器:回调

    这是一个非常基本的示例,只需将您的模型数据填充并查看用户界面:

        function mvc_test()
    
        //% THIS is nested scope variable
        this.model = getModel(); 
        this.view = getView();
    
        //% create model
        function model = getModel()
            model.data1 = 1;
        end
    
        //% create view
        function view = getView()
            view.hfig = figure();
            view.hbtn = uicontrol( 'style', 'push', 'string', 'click me', 'callback', @btn1_cb );
        end
    
        //% controller
        function btn1_cb(varargin)
            this.model.data1 = this.model.data1 + 1;
            set( this.view.hbtn, 'string', num2str(this.model.data1) );
        end
        end
    

    【讨论】:

      【解决方案3】:

      我刚刚研究过在 Matlab 中做 MVC,并提出了一个我认为可行的模式,因为 Matlab 的局限性。主要问题是 GUI 文件是图形对象句柄而不是类。但是,如果将 GUI 包装在视图类中,则可以订阅模型类中的可观察属性。您必须放弃在 GUI 中使用句柄结构来存储所有用户数据……这与设计模式不符。好消息是,Matlab 类很好地支持事件和侦听器,包括我提到的可观察属性。

      我的解决方案演示可以在 Matlab Central File Exchange 上找到,地址为http://www.mathworks.com/matlabcentral/fileexchange/40294-model-view-control-pattern-using-guide
      更详细的实现描述在http://myunscriptedblog.blogspot.com/2013/02/mvc-in-matlab.html的博客文章中

      【讨论】:

      • 优秀的博文。出于 SO 的目的,您可能希望将其放入您的答案中(以避免链接失效)。
      猜你喜欢
      • 1970-01-01
      • 2023-03-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-08
      • 2011-12-03
      • 1970-01-01
      • 2014-02-13
      相关资源
      最近更新 更多