- 1. 背景需求
- 2. 实现步骤
- 2.1. 定义 Model(数据模型)
- 2.1.1. DataModel.h
- 2.1.2. DataModel.cpp
- 2.2. 定义 ViewModel(视图模型)
- 2.2.1. PersonViewModel.h
- 2.2.2. PersonViewModel.cpp
- 2.3. 在 QML 中使用 ViewModel
- 2.3.1. main.cpp
- 2.4. QML 文件
- 2.4.1. main.qml
- 2.5. 运行效果
- 2.5.1. 总结
- 2.1. 定义 Model(数据模型)
1. 背景需求
在 QML 中加载 C++ 数据是一种常见的需求,尤其是在需要处理复杂逻辑或调用系统功能时。通过将 C++ 数据和功能暴露给 QML,可以充分利用 Qt 的强大功能。
在C#开发有代码后置的概念,比如MVVM模式,这种做法有助于将界面展示逻辑与业务逻辑分离,提高代码的可维护性和可测试性。
QML中通常通过在QML文件中引用外部JavaScript文件或C++类来实现。可以将逻辑代码放在单独的 JavaScript 文件中,或者使用 C++ 来实现更复杂的逻辑。这样也能让 QML 代码保持简洁。称之为代码后置。
关于MVVM设计模式的实现,QML非常适合实现,因为它支持数据绑定,可以轻松地将视图与视图模型连接起来。以下是一个简单的示例,展示如何在QML中应用MVVM模式:
好的,以下是一个使用 C++ 来定义 Model 和 ViewModel,并在 QML 中使用的完整示例。
2. 实现步骤
2.1. 定义 Model(数据模型)
Model 是数据的来源,通常是一个简单的类,用于存储和管理数据。
2.1.1. DataModel.h
#ifndef DATAMODEL_H#define DATAMODEL_H#include <QObject>#include <QString>class DataModel : public QObject {Q_OBJECTQ_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)Q_PROPERTY(int age READ age WRITE setAge NOTIFY ageChanged)public:explicit DataModel(QObject *parent = nullptr);QString name() const;void setName(const QString &name);int age() const;void setAge(int age);signals:void nameChanged();void ageChanged();private:QString m_name;int m_age;
};#endif // DATAMODEL_H
2.1.2. DataModel.cpp
#include "DataModel.h"DataModel::DataModel(QObject *parent) : QObject(parent) {m_name="";m_age=0;
}QString DataModel::name() const {return m_name;
}void DataModel::setName(const QString &name) {if (m_name != name) {m_name = name;emit nameChanged();}
}int DataModel::age() const {return m_age;
}void DataModel::setAge(int age) {if (m_age != age) {m_age = age;emit ageChanged();}
}
2.2. 定义 ViewModel(视图模型)
ViewModel 是 Model 和 View 之间的桥梁,负责处理业务逻辑和数据绑定。
2.2.1. PersonViewModel.h
#ifndef PERSONVIEWMODEL_H#define PERSONVIEWMODEL_H#include <QObject>#include "DataModel.h"class PersonViewModel : public QObject {Q_OBJECTQ_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)Q_PROPERTY(int age READ age WRITE setAge NOTIFY ageChanged)public:explicit PersonViewModel(QObject *parent = nullptr);QString name() const;void setName(const QString &name);int age() const;void setAge(int age);signals:void nameChanged();void ageChanged();private:DataModel *m_model;
};#endif // PERSONVIEWMODEL_H
2.2.2. PersonViewModel.cpp
#include "PersonViewModel.h"PersonViewModel::PersonViewModel(QObject *parent) : QObject(parent), m_model(new DataModel(this)) {}QString PersonViewModel::name() const {return m_model->name();
}void PersonViewModel::setName(const QString &name) {m_model->setName(name);emit nameChanged();
}int PersonViewModel::age() const {return m_model->age();
}void PersonViewModel::setAge(int age) {m_model->setAge(age);emit ageChanged();
}
2.3. 在 QML 中使用 ViewModel
在 main.cpp
中,将 PersonViewModel
注册到 QML 引擎中,使其可以在 QML 文件中使用。
2.3.1. main.cpp
#include <QGuiApplication>#include <QQmlApplicationEngine>#include <QQmlContext>#include "PersonViewModel.h"int main(int argc, char *argv[]) {QGuiApplication app(argc, argv);QQmlApplicationEngine engine;// 创建 PersonViewModel 实例并注册到 QMLPersonViewModel viewModel;engine.rootContext()->setContextProperty("viewModel", &viewModel);engine.load(QUrl(QStringLiteral("qrc:/main.qml")));if (engine.rootObjects().isEmpty())return -1;return app.exec();
}
2.4. QML 文件
在 QML 文件中,通过 viewModel
对象访问和更新数据。
2.4.1. main.qml
import QtQuick 2.15import QtQuick.Controls 2.15ApplicationWindow {visible: truewidth: 400height: 300title: "MVVM Example"Column {anchors.centerIn: parentspacing: 10Text {text: "Name: " + viewModel.name}TextField {placeholderText: "Enter name"text: viewModel.nameonEditingFinished: viewModel.name = text}Text {text: "Age: " + viewModel.age}TextField {placeholderText: "Enter age"text: viewModel.age.toString()onEditingFinished: viewModel.age = parseInt(text)}}
}
2.5. 运行效果
- ViewModel:
PersonViewModel
提供了name
和age
属性,并通过Q_PROPERTY
定义了这些属性的 getter 和 setter 方法。 - Model:
DataModel
存储了实际的数据,并通过信号通知 ViewModel 数据的变化。 - View:QML 文件通过
viewModel
对象访问和更新数据,实现了双向数据绑定。
当你运行程序时,你可以通过输入框修改 name
和 age
的值,这些值会实时更新到 Model 中,并反映在界面上。
2.5.1. 总结
通过这种方式,你可以在 QML 中实现类似于 C# 的 MVVM 模式,将数据(Model)、业务逻辑(ViewModel)和用户界面(View)分离,提高代码的可维护性和可测试性。