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 <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.2
import QtQuick.Controls 1.1 ApplicationWindow
{
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 <QObject> 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 <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.2
import QtQuick.Controls 1.1
import CPlusPlus.Test 1.0 ApplicationWindow
{
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 <QObject> 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 <QApplication>
#include <QQmlApplicationEngine>
#include <QtQml>
#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<CPlusPlusSingleton>(
"CPlusPlus.Test", // 统一资源标识符
1, // 主版本号
0, // 次版本号
"CPlusPlusSingleton", // 单例名称
CPlusPlusSingletonRegisterFunc ); // 函数名 QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:///main.qml"))); return app.exec();
}

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

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


import QtQuick 2.2
import QtQuick.Controls 1.1
import CPlusPlus.Test 1.0 ApplicationWindow
{
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++的函数,广告显示效果例如以下:

articleid=37359873" style="color:rgb(51,102,153); text-decoration:none; font-family:Arial; font-size:14px; line-height:26px">本文參加了CSDN博文大赛。请我们支持我,选我。

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

Qt移动应用开发(六):QML与C++互动的更多相关文章

  1. Qt移动应用开发(八):实现跨平台的QML和OpenGL混合渲染

    Qt移动应用开发(八):实现跨平台的QML和OpenGL混合渲染 上一篇文章讲到了利用C++这个桥梁,我们实现了QML和Java的交互.Qt 5大力推崇的QML/JS开发,让轻量.高速开发的QML/J ...

  2. 【Qt编程】基于Qt的词典开发系列<六>--界面美化设计

    本文讲一讲界面设计,作品要面向用户,界面设计的好坏直接影响到用户的体验.现在的窗口设计基本都是扁平化的,你可以从window XP与window 8的窗口可以明显感觉出来.当然除了窗口本身的效果,窗口 ...

  3. Qt for Android开发环境搭建及测试过程记录

    最近学习了Qt的QML编程技术,感觉相较于以前的QtGUI来说更方便一些,使用QML可以将界面与业务逻辑解耦,便于开发. QML支持跨平台,包括支持Android平台,因此可以使用Qt的QML进行An ...

  4. Qt 学习之路:QML 和 QtQuick 2

    前面我们已经了解了 Qt 的一部分内容.这部分内容全部集中在 C++ 方面.也就是说,至今为止我们的程序都是使用 C++ 语言完成的.这在 Qt 5 之前的版本中是唯一的途径.不过,自从 Qt 5 开 ...

  5. Qt for Android 开发大坑

    Qt for Android 开发大坑 作者: qyvlik Qt 5.5.1 这里说一说比較常见的 Qt 开发安卓的大坑. 希望同学们不要做无谓的挣扎,跳过这些坑. 输入框 首当其冲的是输入框,Qt ...

  6. Qt移动应用开发(二):使用动画框架

    Qt移动应用开发(二):使用动画框架 上一篇博客介绍了怎样使用Qt的QML来对屏幕分辨率大小进行适应,其实,不同分辨率的适应是一个很棘手的问题,除了分辨率不同外,宽高比(aspect ratio)也不 ...

  7. Qt移动应用开发(一):适配不同的屏幕

    Qt移动应用开发(一):适配不同的屏幕 到眼下为止.Qt5.3已经出现非常长一段时间了.而且已经有一些应用使用Qt进行构建了.我自己也完毕了第一款使用Qt构建的手机游戏<吃药了>.那么接下 ...

  8. 如何配置一个绿色化的 Qt for Windows 开发环境(有.bat脚本,亲测好用) good

    安装 QtCreator for Windows 其实是很简单的,不过,我一向讨厌什么软件都得弄个安装程序,我希望我所安装的这个 Qt 可以是绿色的.便携的,如果无法实现,至少让这个 Qt 可以在新系 ...

  9. 快速全面了解QT软件界面开发技术

    快速全面了解QT软件界面开发技术     目录 前言 一. 学习QT可能的目的是什么? 只想体验一下QT? 当前的项目选择了用QT. 为将来做QT技术储备. 二. QT的核心技术优势是什么? QT在软 ...

随机推荐

  1. JS学习十四天----server端运行JS代码

    server端运行JS代码 话说,当今不在client使用JS代码才是稀罕事.因为web应用的体验越来越丰富,client用JS实现的逻辑也越来越多,这造成的结果就是某些差点儿一致的逻辑须要在clie ...

  2. ASCII,Unicode和UTF-8终于找到一个能完全搞清楚的文章了

    前言 平时喜欢写东西,看博客,一直对编码有些懵,今天下午也不知道看到了什么,突然想了解下,就找到了这个文章,看完真的豁然开朗,这个必须留下来做纪念. 点击打开链接 1.ASCII 我们知道,计算机内部 ...

  3. [Angular Directive] 3. Handle Events with Angular 2 Directives

    A @Directive can also listen to events on their host element using @HostListener. This allows you to ...

  4. Django之settings.py 的media路径设置

    在一个 models 中使用 FileField 或 ImageField 需要以下步骤: 1. 在你的 settings.py文件中, 定义一个完整路径给MEDIA_ROOT 以便让 Django在 ...

  5. js对时间的操作相关

    摘自网络,我主要用了日期增加若干天之后获得的日期,就是现在是5月2号,我增加30天,应该返回6月几号来着,就是这个意思 用到了Date.prototype.DateAdd 方法,prototype的意 ...

  6. 【图解】Web前端实现相似Excel的电子表格

     在本文中,我将用图解的方式用Wijmo(JavaScript库)中的SpreadJS来一步一步实现网页上的电子表格产品SpreadSheet(比如可构建Office 365 Excel产品.Go ...

  7. AE属性表操作

    转自chanyinhelv原文AE属性表操作 实现的操作包括:1.打开属性表:2.编辑属性表:3.增加属性列:4.数据排序:5.字段计算…… 嗯,实现的功能目前就这些吧,后续还会继续跟进,还望大家多多 ...

  8. hdfs的基本原理和基本操作总结

    hdfs基本原理 Hadoop分布式文件系统(HDFS)被设计成适合执行在通用硬件(commodity hardware)上的分布式文件系统.它和现有的分布式文件系统有非常多共同点. 但同一时候,它和 ...

  9. 小米再迎两位重量级人才,原亦庄国投CEO王晓波入职产投部(产业嗅觉)

    集微网消息,在小米进入上市倒计时阶段,雷军继续在产业链吸纳人才.日前,小米又迎来了两位重量级人才. 一位投资界重量级人才王晓波,他曾任著名产业投资基金亦庄国投总经理.据悉,王晓波加入的部门是小米产投部 ...

  10. ionic新手教程第三课-在项目中使用requirejs分离controller文件和server文件

    继上篇教程中提到的,我们新建一个简单的tabs类型的Ionic项目. 依据文件夹文件我们知道,系统自己主动创建了一个controller文件和server文件,而且把全部的控制器和服务都写到这两个文件 ...