Qt到QML的枚舉綁定
QML中是不支持c++的枚舉類型的,所以我們可以使用Qt的元對象系統,即MOS,來幫助我們實現。
進行綁定的好處就是,以后數據發生變化的時候,就是枚舉發生增加修改,添加等的時候,不需要在QML中進行修改了。
CombBox的model綁定C++的enum
- 實現C++類,這個類要繼承QObject或者其子類
- 使用Q_ENUMS宏定義將我們需要暴露給QML環境中的數據進行包裹
//.hpp文件
#include <QObject>class TestEnum : public QObject
{Q_OBJECTQ_ENUMS(myAlg)
public:enum class myAlg //class關鍵字在這里是c++11開始使用的,針對enum做了改進{AAA,BBB,CCC,DDD};explicit TestEnum(QObject *parent = nullptr);~TestEnum();
signals:public slots:
};
//這個是.cpp文件
TestEnum::TestEnum(QObject *parent) : QObject(parent)
{}TestEnum::~TestEnum()
{}
- 將枚舉導出到QML中的model,首先需要include QQmlContext頭文件
//main.cpp文件#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext> //這個必須include#include "testenum.hpp"int main(int argc, char *argv[])
{
#if defined(Q_OS_WIN)QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
#endifQGuiApplication app(argc, argv);QQmlApplicationEngine engine;TestEnum testEnum; //實例化需要導入到QML環境中的類//metaObject函數為QObject基類中的函數,獲取元對象const QMetaObject* metaObj = testEnum.metaObject();//使用QT自帶的元枚舉,indexOfEnumerator是QMetaObject類中的方法,獲取“myAlg”字符串的枚舉//返回枚舉器的索引,enumerator函數根據枚舉器的索引返回元數據QMetaEnum enumType = metaObj->enumerator(metaObj->indexOfEnumerator("myAlg"));//根據返回的元數據,遍歷其key和value,因為c++枚舉本身是int類型,然后添加到QStringList內QStringList list;for(int i=0; i < enumType.keyCount(); ++i){//enumType.key(i)為根據索引獲取索引所代表的值,這里就是枚舉的字符串//value(i)函數就是返回索引值,如果給定的索引值超出范圍將返回-1QString item = QString::fromLatin1(enumType.key(i)) + " "+ QString::number(enumType.value(i));list.append(item);}//QVariant::fromValue(list)將返回QML可以識別的model//這里的myModel為在QML環境中使用的變量名稱,rootContext函數為獲取父類QQmlEngine的指針//使用setContextProperty函數將其以上下文的方式注入QML環境中//所謂的上下文就是隱藏的全局屬性,包括方法engine.rootContext()->setContextProperty("myModel", QVariant::fromValue(list));//這里要注意一點,load函數要在最后執行,否則將會導入上下文屬性異常engine.load(QUrl(QStringLiteral("qrc:/main.qml"))); if (engine.rootObjects().isEmpty())return -1;return app.exec();
}
- QML中使用
QML中直接使用即可,因為我們在main.cpp內已經將他以上下文的形式導入到QML環境內了
import QtQuick 2.10 //這里是Qt 5.10版本,如果你的版本低,自己修改一下
import QtQuick.Controls 2.3 //這里是Qt 5.10版本,如果你的版本低,自己修改一下ApplicationWindow {visible: truewidth: 640height: 480title: qsTr("test")ComboBox{id: cmbx;width: 300;model: myModel;}
}
運行效果:
備注:
1. 建議后面自己進行封裝
2. 通過傳入根對象的方式動態注入