一个简单的MVC模式的 matlab GUI 面向对象编程范例

程序完成功能:

1】显示存款余额

2】具有存取款的功能,并更新显示存取款后的余额

3】存取款的数额通过编辑框进行输入

程序的处理流程:

第一步】构造model实例,用于存放和处理数据

第二步】构造view实例,在构造实例的过程中使用makeController函数为界面创建一个对应的控制器,并将第一步构造的model实例句柄传入赋给obj.modelObj,并给这个model类的事件消息添加一个监听器,这个监听器监听到model实例中的事件信息(balanceChanged)后会调用View类的updateBalance()函数进行相应。

        function obj = View(modelObj)
            obj.viewSize = [100,100,300,200];
            obj.modelObj = modelObj;
            obj.modelObj.addlistener('balanceChanged',@obj.updateBalance);
            obj.buildUI();
            obj.controlObj = obj.makeController();
            obj.attachToController(obj.controlObj);
        end
       

        function controlObj = makeController(obj)
            controlObj = Controller(obj,obj.modelObj);
        end

第三步】用View类的buildUI函数绘制主界面

function buildUI(obj)
            obj.hfig = figure('pos',obj.viewSize);
            
            obj.drawButton = uicontrol('parent',obj.hfig,'string','withdraw','pos',[60,28,60,28]);
            obj.depositButton = uicontrol('parent',obj.hfig,'string','deposit','pos',[180,28,60,28]);
            
            obj.numBox = uicontrol('parent',obj.hfig,'style','edit','pos',[60,85,180,28],...
                'tag','numBox');
            obj.balanceBox = uicontrol('parent',obj.hfig,'style','edit','pos',[180,142,60,28],...
                'tag','balancebox');
            obj.text = uicontrol('parent',obj.hfig,'style','text','string','balance','pos',[60,142,60,28]);
            
            obj.updateBalance();
        end

 第四步】为主界面的按键添加控制器回调函数

        function attachToController(obj,controller)
            funcH = @controller.callback_drawbutton;
            set(obj.drawButton,'callback',funcH);
            funcH = @controller.callback_depositbutton;
            set(obj.depositButton,'callback',funcH);
        end

第五步】按键后,对应的controller类回调函数被调用,并按照回调函数获取输入数据并对数据进行处理

        function callback_drawbutton(obj,src,event)
            obj.modelObj.withdraw(obj.viewObj.input);
        end
        function callback_depositbutton(obj,src,event)
            obj.modelObj.deposit(obj.viewObj.input);
        end

其中回调函数调用了View类的dependent properties:obj.viewObj.input,这个变量是一个具有函数性质的变量,其具体的值取决于他的实现:实现中通过get方法获取变量input的值(get.input);这个变量input的值来源于传入的参数obj,通过获取obj.nuBox中的值赋值给get.input的返回参数input,实现变量input的确定。这里面返回参数input和成员变量input不是一回事儿,返回参数input只是个形式,在获取input的值的时候,调用的是成员变量input,也就说填入viewObj.input就相当于调用了函数get.input(),进而就获取了返回参数input的值,这个值就被赋给了viewObj.input,然后viewObj.input再作为model类obj.modelObj.withdraw函数的传入参数传了进去,进行下一步的处理。这样一圈就完成了从输入框中获取输入值的功能。

    properties(Dependent)
        input;
    end

        function input = get.input(obj)
            input = get(obj.numBox,'string');
            input = str2double(input);
        end
    

第六步】 Model类中的数据处理函数响应 按键的回调函数,对数据进行处理,并触发model类的事件通知

    events
        balanceChanged
    end


        function deposit(obj,val)
            obj.balance = obj.balance + val;
            obj.notify('balanceChanged');
        end
        
        function withdraw(obj,val)
            obj.balance = obj.balance - val;
            obj.notify('balanceChanged');
        end

 第七步】因为第二步的时候再view类中给model类添加了一个事件监听器,现在发生了事件消息后,监听相应程序会根据事件做出下一步显示信息的更新,完成对事件信息的响应。

        function updateBalance(obj,scr,data)
            set(obj.balanceBox,'string',num2str(obj.modelObj.balance));
        end

 经过以上这样一套循环机制,就完成了按键的整个响应过程。

 

以下是程序的完整代码:

主程序

clc
clear 
close all

modelObj = Model(500);
viewObj = View(modelObj);

M(model)类

classdef Model < handle
    properties
        balance
    end
    
    events
        balanceChanged
    end
    
    methods
        function obj = Model(balance)
            obj.balance = balance;
        end
        
        function deposit(obj,val)
            obj.balance = obj.balance + val;
            obj.notify('balanceChanged');
        end
        
        function withdraw(obj,val)
            obj.balance = obj.balance - val;
            obj.notify('balanceChanged');
        end
    end
end

V(view)类

classdef View < handle
    properties
        viewSize;
        hfig;
        drawButton;
        depositButton;
        balanceBox;
        numBox;
        text;
        modelObj;
        controlObj;
    end
    properties(Dependent)
        input;
    end
    methods
        function obj = View(modelObj)
            obj.viewSize = [100,100,300,200];
            obj.modelObj = modelObj;
            obj.modelObj.addlistener('balanceChanged',@obj.updateBalance);
            obj.buildUI();
            obj.controlObj = obj.makeController();
            obj.attachToController(obj.controlObj);
        end
        function input = get.input(obj)
            input = get(obj.numBox,'string');
            input = str2double(input);
        end
        
        function buildUI(obj)
            obj.hfig = figure('pos',obj.viewSize);
            
            obj.drawButton = uicontrol('parent',obj.hfig,'string','withdraw','pos',[60,28,60,28]);
            obj.depositButton = uicontrol('parent',obj.hfig,'string','deposit','pos',[180,28,60,28]);
            
            obj.numBox = uicontrol('parent',obj.hfig,'style','edit','pos',[60,85,180,28],...
                'tag','numBox');
            obj.balanceBox = uicontrol('parent',obj.hfig,'style','edit','pos',[180,142,60,28],...
                'tag','balancebox');
            obj.text = uicontrol('parent',obj.hfig,'style','text','string','balance','pos',[60,142,60,28]);
            
            obj.updateBalance();
        end
        
        function updateBalance(obj,scr,data)
            set(obj.balanceBox,'string',num2str(obj.modelObj.balance));
        end
        
        function controlObj = makeController(obj)
            controlObj = Controller(obj,obj.modelObj);
        end
        
        function attachToController(obj,controller)
            funcH = @controller.callback_drawbutton;
            set(obj.drawButton,'callback',funcH);
            funcH = @controller.callback_depositbutton;
            set(obj.depositButton,'callback',funcH);
        end
    end
end

C(controller)类

classdef Controller < handle
    properties
        viewObj;
        modelObj;
    end
    methods
        function obj = Controller(viewObj,modelObj)
            obj.viewObj = viewObj;
            obj.modelObj = modelObj;
        end
        
        function callback_drawbutton(obj,src,event)
            obj.modelObj.withdraw(obj.viewObj.input);
        end
        function callback_depositbutton(obj,src,event)
            obj.modelObj.deposit(obj.viewObj.input);
        end
    end
end

 

Context 类

classdef Context < handle
    properties
        dataDictionary;
    end
    
    methods(Static)
        function obj = getInstance()
            persistent localObj;
            if(isempty(localObj)) || ~isvalid(localObj)
                localObj = Context();
            end
            obj = localObj;
        end
    end
    methods (Access = private)
        function obj = Context()
            obj.dataDictionary = containers.Map();
        end
    end
    methods
        
        function register(obj,ID,data) %#ok<INUSD>
            expr = sprintf('obj.dataDictionary(\''%s\'') = data',ID);
            eval(expr);
        end
        
        function data = getData(obj,ID)
            if isKey(obj.dataDictionary,ID)
                data = obj.dataDictionary(ID);
            else
                error('ID NOT EXIST');
            end
        end
    end
end

Context 类的使用

clc
clear 
close all

obj1 = Model('ca');
obj2 = Model('po');

contextObj = Context.getInstance();
contextObj.register('Camera',obj1);
contextObj.register('PowerSource',obj2);

disp(keys(contextObj.dataDictionary));
disp(values(contextObj.dataDictionary));

hCa = contextObj.getData('Camera')

复合布局

clc
clear
close all

f = figure('Menubar','none','Toolbar','none','pos',[200,200,500,500]);
% plot(1:9,[1,2,5,3,6,4,7,8,9])
mainLayout = uiextras.HBox('Parent',f,'Spacing',10);
    leftLayout = uiextras.VBox('Parent',mainLayout,'spacing',10,'Padding',5);
        lUpperLayout = uiextras.VBox('Parent',leftLayout);
        lLowerLayout = uiextras.VBox('Parent',leftLayout);
    
    rightLayout = uiextras.VBox('Parent',mainLayout,'spacing',10);
    
box = uicontrol('parent',lUpperLayout,'string','leftUpperButton');
box2 = axes('parent',lLowerLayout);
box3 = axes('parent',rightLayout);
plot(box3,1:9,[1,2,5,3,6,4,7,8,9])
plot(box2,1:9,[1,2,5,3,6,4,7,8,9])

 

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值