Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
411 views
in Technique[技术] by (71.8m points)

model view controller - how to implement the idea of mvc design in matlab gui's

please am a student working on a project to develop a visualization tool to analyse data using an mvc design in matlab. but the problem im having is that im new to programming and matlab is the first real programing im doing. ive pretty much done the codes but i fear they are no way in an mvc design pattern so i need to change this.

would really appreciate as many imputes as possible to link me up with useful materials as i cant find any for mvc in matlab or may be exemplar codes that implement mvc in matlab to help give me an idea of how i can do mine, presently and doing things like this, where data is a structure with fileds for .Name and .Data. the functions/ methods datcorrCoef and datCorrSum are function i have created that accept my data object as arguments


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)

and i have done the callback/ control as follows;

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)

where i again have other functions that operate with my data object here in the controller; really frustrated about the whole thing!! please let me know if im not being clear enough about the description of my problem so you can please help out. thank you

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

For MVC you need proper Object-Orientation. OO in MATLAB is available in the newer versions, you can just do it like you would do MVC in Java. But it does not "feel" right in MATLAB (so I do not think your instructor meant this) because it would be an overkill in most simple cases and for complex/large UI's MATLAB is too slow and has performance issues in some scenarios.

Otherwise you can use nested functions (closures in CS). With closures some OO functionality can be "emulated". The only problem is that everything has to stay in one m-file.

  • Model: nested scope variable (here named "this")
  • View: uicontrols (and other ui elements)
  • Controller: callbacks

Here is a very basic example, just fill it with your model data and view ui's:

    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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...