Qt移动应用开发(六):QML与C++的交互

Qt移动应用开发(六):QML与C++的交互

上一篇文章讲到了在Qt Quick中实现场景切换的一种可能的方法,场景切换是诸如游戏等应用在内必须要面临的技术难点,所以场景切换并没有通行的方法,根据自己的使用习惯进行设计即可。

本文主要介绍的是如何使用QML和C++进行交互,难度稍微偏大,适合有经验的Qt开发者进行学习交流。

Qt 5吸收了Qt 4的declarative模块的优点,对底层进行了更改,新建了QPA层,隔离了不同操作系统API和上层Qt代码,同时QML/QtQuick也可以顺利在不同平台上运行。另外由于考虑到让Qt程序接入不同的库函数,因此Qt开放了接口让QML层和C++代码进行交互。之前已经有较多介绍QML与C++交互的文章了,本文仅作为一种有益的补充,更多相关的知识可以查询Qt帮助文档或向我留言。

本文的例子在Qt 5.3.1中顺利编译运行通过。

原创文章,反对未声明的引用。原博客地址:

首先一个较为简单的方法就是注册上下文属性(Context Property),让QML访问C++的变量。代码如下:

#include <QApplication>#include <QQmlApplicationEngine>#include <QQmlContext>int main(int argc, char *argv[]){QApplication app(argc, argv);QQmlApplicationEngine engine;engine.rootContext( )->setContextProperty("Greeting",QObject::tr( "Hello QML from C++" ) );engine.load(QUrl(QStringLiteral("qrc:///main.qml")));return app.exec();}

然后在QML中简单地调用”Greeting”变量名就可以顺利访问了。

import QtQuick 2.2import QtQuick.Controls 1.1ApplicationWindow{visible: truewidth: 640height: 480title: qsTr("测试QML于C++的交互")menuBar: MenuBar{Menu{title: qsTr("文件")MenuItem{text: qsTr("退出")onTriggered: Qt.quit( );}}}Text{text: qsTr("本例用来测试QML和C++的交互")anchors.right: parent.rightanchors.bottom: parent.bottom}Text{text: Greetinganchors.centerIn: parent}}

演示程序的截图如下:

本例重要的部分是QQmlContext实例指针。它通过QQmlApplicationEngine::rootContext()来获得,也可以通过QQmlApplicationEngine:: contextForObject(constQObject * object)来获得。在QQmlObject创建的时候,都会实例化一个QQmlContext,用来支持为运行环境提供的上下文属性。

使用上下文属性可以让QML访问C++数据,那么如何使用QML来访问C++的函数呢?这里我们在C++中注册QML类或者单例来让QML来获得访问C++函数的机会。首先介绍一下如何将QML中注册C++类到QML中。首先需要定义一个C++类继承于QObject,然后这么写:

#ifndef CPLUSPLUSCLASS_H#define CPLUSPLUSCLASS_H#include <QObject>class CPlusPlusClass: public QObject{Q_OBJECTQ_PROPERTY( int rating READ rating )public:explicit CPlusPlusClass( QObject* pParent = Q_NULLPTR ):QObject( pParent ){m_Rating = 5;}Q_INVOKABLE void method( void ){qDebug( "[C++]%s is called.", __FUNCTION__ );}int rating( void ) { return m_Rating; }private:int m_Rating;};#endif // CPLUSPLUSCLASS_H

然后再main.cpp中需要调用qmlRegisterType()模板函数来注册C++类到QML中,一个典型的用法如下:

#include <QApplication>#include <QQmlApplicationEngine>#include <QtQml>#include "CPlusPlusClass.h"int main(int argc, char *argv[]){QApplication app(argc, argv);// 首先注册一下类qmlRegisterType<CPlusPlusClass>("CPlusPlus.Test",// 统一资源标识符1,// 主版本0,// 次版本"CPlusPlusType" );// QML类名称QQmlApplicationEngine engine;engine.load(QUrl(QStringLiteral("qrc:///main.qml")));return app.exec();}

最后在QML中就可以顺利地访问C++类的属性和方法了:

import QtQuick 2.2import QtQuick.Controls 1.1import CPlusPlus.Test 1.0ApplicationWindow{visible: truewidth: 640height: 480title: qsTr("测试QML于C++的交互")menuBar: MenuBar{Menu{title: qsTr("文件")MenuItem{text: qsTr("退出")onTriggered: Qt.quit( );}}}Text{text: qsTr("本例用来测试QML和C++的交互")anchors.right: parent.rightanchors.bottom: parent.bottom}CPlusPlusType{id: theType}MouseArea{anchors.fill: parentonClicked:{console.log( "[qml] Rating is: " + theType.rating );theType.method( );}}}

点击窗体,控制台运行结果如下:

qml: [qml] Ratingis: 5

[C++]method iscalled.

如果不想在QML和C++环境中创建多个QObject或者说想要更加方便地访问C++的方法,那么可以考虑注册一个单例类,,注册单例类和注册普通的类差不多,但也有一些显著的区别,首先建立这样一个继承于QObject的类,代码如下:

#ifndef CPLUSPLUSCLASS_H#define CPLUSPLUSCLASS_H#include <QObject>class CPlusPlusClass: public QObject{Q_OBJECTQ_PROPERTY( int rating READ rating )public:explicit CPlusPlusClass( QObject* pParent = Q_NULLPTR ):QObject( pParent ){m_Rating = 5;}Q_INVOKABLE void method( void ){qDebug( "[C++]%s is called.", __FUNCTION__ );}int rating( void ) { return m_Rating; }private:int m_Rating;};#endif // CPLUSPLUSCLASS_H接受失败也等于给了自己从零开始的机会,接受失败更是一种智者的宣言和呐喊;

Qt移动应用开发(六):QML与C++的交互

相关文章:

你感兴趣的文章:

标签云: