一、引言 在QtQuick开发中,QML应用程序通常需要用C来处理高级和性能密集型的任务。为了实现这一点,最常见、最便捷的方法是:向QML运行时环境公开C类(注意:该C类必须派生自QObject),在Qt5。7或更高版本中,本文将描述以下两个问题:(1)如何在QML应用程序中使用C类。 (2)向QML导出C方法(包括槽函数)二、如何在QML应用程序中使用C类(21)创建一个C类:classDatasdatas。h头文件ifndefDATASHdefineDATASHincludeQObjectincludeQStringclassDatas:publicQObject{QOBJECTQPROPERTY(QStringmageREADgetAgeWRITEsetAgeNOTIFYageChanged)public:explicitDatas(QObjectparentnullptr);QStringgetAge(){returnmage;}voidsetAge(constQStringage){mageage;emitageChanged();}signals:voidageChanged();private:QStringmage;};endifDATASHdatas。cppincludedatas。hDatas::Datas(QObjectparent):QObject(parent),mage(25){} 上述代码中,在C类中使用QPROPERTY宏声明了一个可以从QML访问的属性,这里是mage属性;并声明了读、写该属性的方法:getAge()和setAge();同时声明了该属性改变时所发出的信号:ageChanged():QPROPERTY(QStringmageREADgetAgeWRITEsetAgeNOTIFYageChanged)(22)注册C类 在上述步骤中,我们定义了一个C类,为了在QML环境中使用该类,需要将它注册到QML上下文环境中: main。cincludeQGuiApplicationincludeQQmlApplicationEngineincludeQQmlContextincludedatas。hintmain(intargc,charargv〔〕){ifQTVERSIONQTVERSIONCHECK(6,0,0)QCoreApplication::setAttribute(Qt::AAEnableHighDpiScaling);endifQGuiApplicationapp(argc,argv);QQmlApplicationEngineengine;Datasmdatas;QQmlContextqmlctxengine。rootContext();qmlctxsetContextProperty(cppdatas,mdatas);constQUrlurl(QStringLiteral(qrc:main。qml));QObject::connect(engine,QQmlApplicationEngine::objectCreated,app,〔url〕(QObjectobj,constQUrlobjUrl){if(!objurlobjUrl)QCoreApplication::exit(1);},Qt::QueuedConnection);engine。load(url);returnapp。exec();} 使用QQmlContex的setContextProperty()成员函数向QML运行上下文环境注册C类型,如下:Datasmdatas;QQmlContextqmlctxengine。rootContext();qmlctxsetContextProperty(cppdatas,mdatas);注册mdatas(23)在QML中使用C类中声明的数据。 在main。c文件中,我们已经将Datas类的实例mdatas注册到到了QML运行上下文环境中,接下来,我们则可以在QML中使用该类中声明的数据了: main。qml文件importQtQuick2。15importQtQuick。Window2。15importQtQuick。Controls2。15Window{id:windowwidth:640height:480visible:truecolor:117c90title:qsTr(演示Author:iriczhao)Button{id:buttonx:270y:345text:qsTr(Click)onClicked:{label。textcppdatas。mage;}}Label{id:labelx:168y:134width:305height:45color:fffffftext:qsTr(iriczhao)horizontalAlignment:Text。AlignHCenterverticalAlignment:Text。AlignVCenterfont。bold:true}} 如上代码所示,在应用中放置了一个Button和Label,当点击Button后,Label标签的文本属性将被C类中的mage赋值。即应用界面将显示25。(24)效果 三、向QML导出C方法(包括槽函数) 在上文中,描述了如何向QML公开C类的数据属性。那么对于C类的方法同样也能公开给QML。具体步骤如下:(31)声明C成员函数 对于QObject派生类型的所有方法都可以从QML代码中访问。例如: (1)使用QINVOKABLE宏标记的公共方法。 (2)QtC公共槽函数。 如下代码片段:classMessageBoard:publicQObject{QOBJECTpublic:QINVOKABLEboolpostMessage(constQStringmsg){qDebug()CalledtheCmethodwithmsg;returntrue;}publicslots:voidrefresh(){qDebug()CalledtheCslot;}}; postMessage()函数使用QINVOKABLE标记;refresh()函数是一个公共槽函数,所以这两个函数都能从QML中访问。(32)注册C类 同样的,为了使用C类中的方法(包括槽函数),需要将C类注册到QML上下文环境中(这里是MessageBoard类):MessageBoardmsgBoard;实例MessageBoardview。engine()rootContext()setContextProperty(cppmsgBoard,msgBoard);将msgBoard注册到QML上下文环境中(33)在QML中使用C类的方法 如下代码片段:importQtQuick2。0Item{width:100;height:100MouseArea{anchors。fill:parentonClicked:{varresultmsgBoard。postMessage(HellofromQML)console。log(ResultofpostMessage():,result)msgBoard。refresh();}} 上述代码中,使用msgBoard调用postMessage()和refresh()方法访问到了C类中的方法。四、总结 (1)如果需要在QML中访问C类中的数据成员。需要使用QPROPERTY声明该数据成员,并声明对数据成员的读、写函数以及数据改变时的关联信号。 然后使用QQmlContex的setContextProperty()将C类注册到QML上下文中。 (2)如果需要在QML中访问C方法(包括槽函数),这里分为两种情况:如果该函数是一个公共函数,我们需要使用QINVOKABLE宏去标记它。如果是一个公共的槽函数,则可以直接访问。 同样的,使用QQmlContex的setContextProperty()将C类注册到QML上下文中。 搜索关注嵌入式小生vx公众号,获取更多精彩内容。