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进阶 11-21 纯css实现选项卡

    js进阶 11-21 纯css实现选项卡 一.总结 一句话总结:核心原理,a标签的锚点效果+父div限宽+多的部分隐藏. 1.如何实现a标签的锚点效果? href属性找到对应的位置就好,和选择器一样, ...

  2. mac nginx php-fpm

    再一次被困在一个傻问题.由于我居然怀疑是不是mac本身就和centos的安装不一样.在一次次地排错后,最终发现.原来是我的nginx.conf的一行配置少写了一个字母.最后多亏用ls检查来定位到这个错 ...

  3. nyoj 949哈利波特(细节题)

    哈利波特 时间限制:1000 ms  |  内存限制:65535 KB 难度:3 描写叙述 Harry 新学了三种魔法.他能够用第一种魔法把 a 克的沙子变成 b 克金属,能够用另外一种魔法把 c 克 ...

  4. 【19.46%】【codeforces 551B】ZgukistringZ

    time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...

  5. [NPM] Pass arguments to npm scripts

    Often times you’ll have variations that you’ll want to make to your npm scripts and repeating yourse ...

  6. 编写ATL控件的简单做法

    作者:朱金灿 来源:http://blog.csdn.net/clever101 ATL并不像MFC库那样提供了很多的控件窗口类,因此要使用ATL的话需要自己去封装.封装的做法很简单.比如现在我需要一 ...

  7. ITFriend创业败局(四):菜鸟CEO的自我修养

    自创业自封CEO以来,短短3个月,又经历了无数的磨练,快速成长中. 创业不同于打工,他要求你必须有全局观和综合能力,技术.市场.商务,啥都得会,还要处理各种各样的问题和矛盾. 根据个人经历,我总结了以 ...

  8. Tomcat的JVM经常挂掉,根据hs_err_pid23224.log这种日志文件,也没能发现具体是什么原因导致的

    ## A fatal error has been detected by the Java Runtime Environment:##  SIGBUS (0x7) at pc=0x00007f1a ...

  9. Linux非图形界面安装程序

    安装Linux程序的时候一般不会调取图形界面,这样输错内容,返回上一步时需要使用命令 previous ,相应的exit 与 next..在中文操作的时候,不会提示,所以要记住 在安装过程中,我们可能 ...

  10. Javascript中的DOM实现显示鼠标的空间位置

    为了显示鼠标相对于浏览器的位置(相对于屏幕和页面类似),我们能够利用click事件,获得关于鼠标单击的事件对象event.这个事件对象里的clientX和clientY包括了鼠标的位置信息,所以我突发 ...