как реализовать идею дизайна MVC в Matlab Gui's - PullRequest
2 голосов
/ 16 августа 2010

Пожалуйста, студент, работающий над проектом по разработке инструмента визуализации для анализа данных с использованием mvc design в matlab.но проблема, с которой я столкнулся, в том, что я новичок в программировании, и Matlab - это первое настоящее программирование, которое я делаю.Я довольно много сделал кодов, но я боюсь, что они не в шаблоне дизайна MVC, поэтому мне нужно изменить это.

был бы очень признателен как можно большему числу вменяемых, чтобы связать меня с полезными материалами, поскольку я не могу найти ни одного для mvc в matlab, или, может быть, это примеры кода, которые реализуют mvc в matlab, чтобы помочь мне понять, как я могуделаю мой, в настоящее время и делаю такие вещи, где данные - это структура с полями для .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)

где у меня снова есть другие функции, которые работают с моим объектом данных здесь, в контроллере;действительно разочарован всем этим !!пожалуйста, дайте мне знать, если я не достаточно ясен в описании моей проблемы, чтобы вы могли помочь.спасибо

Ответы [ 3 ]

5 голосов
/ 16 августа 2010

Для MVC вам нужна правильная объектная ориентация.OO в MATLAB доступен в более новых версиях, вы можете сделать это так же, как MVC в Java.Но он не «чувствует» себя правильно в MATLAB (так что я не думаю, что ваш инструктор имел в виду это), потому что это было бы излишним в большинстве простых случаев, а для сложных / больших пользовательских интерфейсов MATLAB слишком медленный и имеет проблемы с производительностью в некоторыхсценарии.

В противном случае вы можете использовать вложенные функции (замыкания в CS).С замыканиями некоторые функции ОО могут быть "эмулированы".Единственная проблема состоит в том, что все должно оставаться в одном m-файле.

  • Модель: вложенная переменная области видимости (здесь она называется "this")
  • View: uicontrols (и другие элементы пользовательского интерфейса))
  • Контроллер: обратные вызовы

Вот очень простой пример, просто заполните его данными своей модели и просмотрите пользовательский интерфейс:

    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
4 голосов
/ 16 августа 2010

То, что вы пытаетесь сделать, - нетривиальная вещь. Система пользовательского интерфейса MATLAB, GUIDE, на самом деле не такая гибкая. Я ненавижу быть негативным по этому поводу. Я ценю, что вы пытаетесь разработать пользовательский интерфейс, следуя шаблону, но я бы просто использовал GUIDE и оставался с автоматически сгенерированными сегментами кода.

Использование Java или C # для пользовательского интерфейса, а затем MATLAB Builder NE или MATLAB Builder Java для ввода MATLAB для тяжелой обработки - гораздо лучший вариант. Я не уверен, что студенческая версия идет с этим, но это действительно то, что вы хотите.

Один из самых важных уроков, которые любой программист может выучить, заключается в том, что у каждого языка есть свои сильные и слабые стороны. Попытка втиснуть язык в парадигму, для которой он не предназначен, - это битва в гору, которая обычно заканчивается больше плача, чем радости.

3 голосов
/ 16 февраля 2013

Я только что посмотрел на создание MVC в Matlab и придумал шаблон, который, я думаю, работает с учетом ограничений Matlab. Основная проблема заключается в том, что файлы 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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...