博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Qt移动应用开发(六):QML与C++互动
阅读量:7114 次
发布时间:2019-06-28

本文共 6303 字,大约阅读时间需要 21 分钟。

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中顺利编译执行通过。

原创文章,反对未声明的引用。原博客地址:http://blog.csdn.net/gamesdev/article/details/37359873

       首先一个较为简单的方法就是注冊上下文属性(Context Property)。让QML訪问C++的变量。

代码例如以下:

 
#include 
#include
#include
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: true    width: 640    height: 480    title: qsTr("測试QML于C++的交互")    menuBar: MenuBar    {        Menu        {            title: qsTr("文件")            MenuItem            {                text: qsTr("退出")                onTriggered: Qt.quit( );            }        }    }    Text    {        text: qsTr("本例用来測试QML和C++的交互")        anchors.right: parent.right        anchors.bottom: parent.bottom    }    Text    {        text: Greeting        anchors.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 
class CPlusPlusClass: public QObject{ Q_OBJECT Q_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 
#include
#include
#include "CPlusPlusClass.h"int main(int argc, char *argv[]){ QApplication app(argc, argv); // 首先注冊一下类 qmlRegisterType
( "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: true    width: 640    height: 480    title: qsTr("測试QML于C++的交互")    menuBar: MenuBar    {        Menu        {            title: qsTr("文件")            MenuItem            {                text: qsTr("退出")                onTriggered: Qt.quit( );            }        }    }    Text    {        text: qsTr("本例用来測试QML和C++的交互")        anchors.right: parent.right        anchors.bottom: parent.bottom    }    CPlusPlusType    {        id: theType    }    MouseArea    {        anchors.fill: parent        onClicked:        {            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 
class CPlusPlusClass: public QObject{ Q_OBJECT Q_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中。除了调用qmlRegisterSingletonType()模板函数外。还须要写一个静态全局的注冊函数。代码例如以下:

 
#include 
#include
#include
#include "CPlusPlusSingleton.h"// 注冊单例函数static QObject* CPlusPlusSingletonRegisterFunc( QQmlEngine* pQMLEngine, QJSEngine* pJSEngine ){ Q_UNUSED( pQMLEngine ); Q_UNUSED( pJSEngine ); CPlusPlusSingleton* pSingleton = new CPlusPlusSingleton; return pSingleton;}int main(int argc, char *argv[]){ QApplication app(argc, argv); // 首先注冊一下单例 qmlRegisterSingletonType
( "CPlusPlus.Test", // 统一资源标识符 1, // 主版本号 0, // 次版本号 "CPlusPlusSingleton", // 单例名称 CPlusPlusSingletonRegisterFunc ); // 函数名 QQmlApplicationEngine engine; engine.load(QUrl(QStringLiteral("qrc:///main.qml"))); return app.exec();}
 

就这样。C++的部分就完毕了。

接下来在QML中就非常easy了:

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

点击窗口。控制台结果例如以下:

qml: [qml] Ratingis: 5

[C++]method iscalled.

       大家能够依据须要选择是否在C++中注冊QML类和注冊C++单例来获得相相应的特性。

       在我的第一款独立游戏《》中,为了顺利地接入广告SDK,须要写C++代码来保证让QML可以訪问到C++的函数,广告显示效果例如以下:

。请我们支持我,选我。

版权声明:本文博客原创文章。博客,未经同意,不得转载。

你可能感兴趣的文章
canvas
查看>>
2018-07-30 到 2018-08-03
查看>>
昨天,我们公司的产品经理被我...
查看>>
【今日头条】【抖音火山】后台开发实习生
查看>>
js文件操作总结一:图片篇
查看>>
外观模式
查看>>
javascript之函数防抖与节流
查看>>
docker 部署前端
查看>>
Spring定时任务的几种实现
查看>>
web前端程序员真的值这么多钱吗?
查看>>
好程序员Java分享JVM结构
查看>>
echarts加轴显示(单位)及标题
查看>>
Java反射 方法 Methods
查看>>
使用工具类DbUtils连接数据库,并简单操作数据库
查看>>
vue/cli3+最全生产环境优化方法
查看>>
日日日日日日日日日日
查看>>
Leetcode #383 Javascript
查看>>
有趣的前端编程题:携程 2018 春招
查看>>
js数据类型--object
查看>>
Vue2.0源码阅读笔记(一):选项合并
查看>>