利用上下文屬性將 C++ 對象嵌入 QML 裡
QQmlContext
類使將 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 } }
到此這篇關於利用上下文屬性將 C++ 對象嵌入 QML 裡的文章就介紹到這瞭,更多相關 C++ 對象嵌入 QML 裡內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!