C++:实现mvvm

最近做了一段时间WPF,印象最深刻就是里面的mvvm模式,打算用C++做一个雏形,并为以后的项目做准备。

首先讲一下我对mvvm的理解(可能会有偏差,各位大佬可以指点),mvvm其实可以分开理解为 model , view ,viewmodel 。model提供数据模型,view就是ui,viewmodel做一些跟ui无关的逻辑(更新数据等),跟传统的mvc对比,control很难摆脱与view的耦合,比如更新ui元素等,长期下来,controler的代码只会越来越臃肿。mvvm是一套基于数据绑定的设计模式。C#本身就支持数据绑定机制,所以实现起来简单得多,但是C++也并非不能实现。

 

先讲一下设计思路

1. 维护一个全局的map来保存属性跟ui行为

2. UI创建的时候建立跟属性(代码里面的propertyName)的关系。

3. Model里面重载=号,在赋值以后,检索m_propertyAct以执行对应的UI更新函数(当然,后面可以设计成事件通知模式,以去除跟view的耦合)

4. Viewmodel里面只需要做一件事情,就是赋值!(是不是很爽有木有?这跟UI完全没有耦合关系)

 

下面贴上我写的一个雏形,以后有空再进行拓展

#include <iostream>
#include <functional>
#include <map>

//模拟数据绑定
const std::string propertyName = "txt";
std::map<std::string, std::function<void(std::string)>> m_propertyAct;

//假定这是一个UI元素
class UIElement
{
public:
    explicit UIElement(std::string property) : _property(property)
    {
        m_propertyAct[property] = std::bind(&UIElement::SetTxt,this,std::placeholders::_1);
    }

private:
    std::string _property;
    std::string _txt;

    void SetTxt(std::string txt)
    {
        //这里可以做一些UI的行为
        _txt = txt;
    }
};

class Model
{
public:
    Model(): _property(propertyName){}
    
    void operator=(const Model& model)
    {
        m_propertyAct[_property](_param);
    }

    std::string _param;
private:
    std::string _property;
};

class ViewModel
{
public :
    ViewModel() {}
    void DoSomething()
    {
        _model = Model();
    }
private:
    Model _model;
};

int main()
{
    auto ui = UIElement(propertyName);
    ViewModel().DoSomething();
    std::cout << "Hello World!\n";
}

 

  • 4
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
MVVM(Model-View-ViewModel)是一种软件架构模式,用于将应用程序的用户界面与其相关的业务逻辑和数据分离开来。 在Qt中实现MVVM架构可以使用以下组件: 1. Model:Qt中的模型通常是QAbstractItemModel的子类,用于提供数据。模型负责数据的读取、存储和更新,也可以发送信号通知视图数据的变化。 2. View:视图负责显示数据和接收用户输入,同时与ViewModel进行交互来获取数据。在Qt中,视图可以是QWidget或QML元素。 3. ViewModel:ViewModel是视图和数据模型之间的中间层,负责处理视图的请求并将其转换为模型能够理解的操作。ViewModel还负责将模型中的数据格式化为视图可以显示的格式,并将视图中的用户输入转换为模型可以理解的操作。 下面是一个简单的Qt MVVM示例: ```cpp // MyModel.h class MyModel : public QAbstractListModel { Q_OBJECT public: explicit MyModel(QObject *parent = nullptr); int rowCount(const QModelIndex &parent) const override; QVariant data(const QModelIndex &index, int role) const override; // ... }; // MyViewModel.h class MyViewModel : public QObject { Q_OBJECT public: explicit MyViewModel(QObject *parent = nullptr); Q_INVOKABLE QVariantList getData() const; Q_INVOKABLE void setData(const QVariantList &data); private: MyModel *m_model; }; // MyView.qml ListView { model: myViewModel.getData() delegate: Text { text: modelData.name } // ... } // main.cpp int main(int argc, char *argv[]) { QCoreApplication app(argc, argv); MyModel model; MyViewModel viewModel; viewModel.setData(model.getData()); QQmlEngine engine; engine.rootContext()->setContextProperty("myViewModel", &viewModel); QQmlComponent component(&engine, QUrl("MyView.qml")); QObject *object = component.create(); // ... return app.exec(); } ``` 在这个示例中,MyModel是一个QAbstractListModel的子类,用于提供数据。MyViewModel是一个QObject的子类,它包含了一个指向MyModel的指针,并提供了两个Q_INVOKABLE函数:getData和setData,用于从模型中获取数据和将数据设置到模型中。MyView是一个QML文件,用于显示数据。它包含一个ListView元素,使用myViewModel.getData()作为模型,并使用一个Text元素作为委托。 在main函数中,我们创建了一个MyModel对象和一个MyViewModel对象,并通过setData将模型中的数据设置到ViewModel中。然后,我们创建了一个QQmlEngine对象,并将myViewModel对象注册到rootContext中。最后,我们使用QQmlComponent创建了一个MyView对象,并将其显示出来。 这只是一个简单的Qt MVVM示例,实际上MVVM框架非常灵活,可以根据具体的需求进行设计和实现

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值