C++ 对象嵌入 QML 里
友善啊,朋友 人气:0QQmlContext
类使将 C++ 数据注入 QML 对象的能力成为可能。此类向 QML 对象的上下文公开数据,以便可以直接从 QML 代码范围内引用数据。
一、设置简单的上下文属性
例如,这里有一个 QML 项,它引用了当前作用域中不存在的 currentDateTime 值:
// MyItem.qml import QtQuick 2.0 Text { text: currentDateTime }
这个值可以由加载 QML 组件的 C++ 应用程序使用 QQmlContext::setContextProperty()
直接设置:
QQuickView view; view.rootContext()->setContextProperty("currentDateTime",QDateTime::currentDateTime()); view.setSource(QUrl::fromLocalFile("MyItem.qml")); view.show();
由于在 QML 中计算的所有表达式都是在特定上下文中计算的,如果修改了上下文,则将重新计算该上下文中的所有绑定。因此,应在应用程序初始化之外谨慎使用上下文属性,因为这可能会导致应用程序性能下降。
二、将对象设置为上下文属性
上下文属性可以包含 QVariant
或 QObject*
值。 这意味着也可以使用这种方法注入自定义 C++ 对象,并且可以直接在 QML 中修改和读取这些对象。修改上面的例子,嵌入一个 QObject 实例而不是一个 QDateTime
值,QML 代码在对象实例上调用一个方法:
class ApplicationData : public QObject { Q_OBJECT public: Q_INVOKABLE QDateTime getCurrentDateTime() const { return QDateTime::currentDateTime(); } }; int main(int argc, char *argv[]) { QGuiApplication app(argc, argv); ApplicationData data; QQuickView view; view.rootContext()->setContextProperty("applicationData", &data); view.setSource(QUrl::fromLocalFile("MyItem.qml")); view.show(); return app.exec(); } // MyItem.qml import QtQuick 2.0 Text { text: applicationData.getCurrentDateTime() }
请注意:从 C++ 返回到 QML 的日期/时间值可以通过 Qt.formatDateTime() 和相关函数进行格式化。
如果 QML 项需要从上下文属性接收信号,它可以使用 Connections
类型连接到它们。 例如,如果 ApplicationData
有一个名为 dataChanged()
的信号,则可以使用 Connections
对象中的 onDataChanged
处理程序连接到该信号:
Text { text: applicationData.getCurrentDateTime() Connections { target: applicationData onDataChanged: console.log("The application data changed!") } }
三、上下文属性与C++ 的数据模型示例
3.1、字符串列表模型
int main(int argc, char ** argv) { QGuiApplication app(argc, argv); QStringList dataList; dataList.append("Item 1"); dataList.append("Item 2"); dataList.append("Item 3"); dataList.append("Item 4"); QQuickView view; QQmlContext *ctxt = view.rootContext(); ctxt->setContextProperty("myModel", QVariant::fromValue(dataList)); view.setSource(QUrl("qrc:view.qml")); view.show(); return app.exec(); }
import QtQuick 2.0 ListView { width: 100; height: 100 model: myModel delegate: Rectangle { height: 25 width: 100 Text { text: modelData } } }
3.2、对象列表模型
#ifndef DATAOBJECT_H #define DATAOBJECT_H #include <QObject> class DataObject : public QObject { Q_OBJECT Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged) Q_PROPERTY(QString color READ color WRITE setColor NOTIFY colorChanged) public: DataObject(QObject *parent=nullptr); DataObject(const QString &name, const QString &color, QObject *parent=nullptr); QString name() const; void setName(const QString &name); QString color() const; void setColor(const QString &color); signals: void nameChanged(); void colorChanged(); private: QString m_name; QString m_color; }; #endif // DATAOBJECT_H
#include <QDebug> #include "dataobject.h" DataObject::DataObject(QObject *parent) : QObject(parent) { } DataObject::DataObject(const QString &name, const QString &color, QObject *parent) : QObject(parent), m_name(name), m_color(color) { } QString DataObject::name() const { return m_name; } void DataObject::setName(const QString &name) { if (name != m_name) { m_name = name; emit nameChanged(); } } QString DataObject::color() const { return m_color; } void DataObject::setColor(const QString &color) { if (color != m_color) { m_color = color; emit colorChanged(); } } #include "dataobject.h" int main(int argc, char ** argv) { QGuiApplication app(argc, argv); QList<QObject*> dataList; dataList.append(new DataObject("Item 1", "red")); dataList.append(new DataObject("Item 2", "green")); dataList.append(new DataObject("Item 3", "blue")); dataList.append(new DataObject("Item 4", "yellow")); QQuickView view; view.setResizeMode(QQuickView::SizeRootObjectToView); QQmlContext *ctxt = view.rootContext(); ctxt->setContextProperty("myModel", QVariant::fromValue(dataList)); view.setSource(QUrl("qrc:view.qml")); view.show(); return app.exec(); } import QtQuick 2.0 ListView { width: 100; height: 100 model: myModel delegate: Rectangle { height: 25 width: 100 color: model.modelData.color Text { text: name } } }
3.3、QAbstractItemModel
#include <QAbstractListModel> #include <QStringList> class Animal { public: Animal(const QString &type, const QString &size); QString type() const; QString size() const; private: QString m_type; QString m_size; }; class AnimalModel : public QAbstractListModel { Q_OBJECT public: enum AnimalRoles { TypeRole = Qt::UserRole + 1, SizeRole }; AnimalModel(QObject *parent = nullptr); void addAnimal(const Animal &animal); int rowCount(const QModelIndex & parent = QModelIndex()) const; QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const; protected: QHash<int, QByteArray> roleNames() const; private: QList<Animal> m_animals; };
#include "model.h" Animal::Animal(const QString &type, const QString &size) : m_type(type), m_size(size) { } QString Animal::type() const { return m_type; } QString Animal::size() const { return m_size; } AnimalModel::AnimalModel(QObject *parent) : QAbstractListModel(parent) { } void AnimalModel::addAnimal(const Animal &animal) { beginInsertRows(QModelIndex(), rowCount(), rowCount()); m_animals << animal; endInsertRows(); } int AnimalModel::rowCount(const QModelIndex & parent) const { Q_UNUSED(parent) return m_animals.count(); } QVariant AnimalModel::data(const QModelIndex & index, int role) const { if (index.row() < 0 || index.row() >= m_animals.count()) return QVariant(); const Animal &animal = m_animals[index.row()]; if (role == TypeRole) return animal.type(); else if (role == SizeRole) return animal.size(); return QVariant(); } QHash<int, QByteArray> AnimalModel::roleNames() const { QHash<int, QByteArray> roles; roles[TypeRole] = "type"; roles[SizeRole] = "size"; return roles; } int main(int argc, char ** argv) { QGuiApplication app(argc, argv); AnimalModel model; model.addAnimal(Animal("Wolf", "Medium")); model.addAnimal(Animal("Polar bear", "Large")); model.addAnimal(Animal("Quoll", "Small")); QQuickView view; view.setResizeMode(QQuickView::SizeRootObjectToView); QQmlContext *ctxt = view.rootContext(); ctxt->setContextProperty("myModel", &model); view.setSource(QUrl("qrc:view.qml")); view.show(); return app.exec(); }
import QtQuick 2.0 ListView { width: 200; height: 250 model: myModel delegate: Text { text: "Animal: " + type + ", " + size } }
加载全部内容