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. 通过传入根对象的方式动态注入