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中顺利编译执行通过。
原创文章,反对未声明的引用。原博客地址: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++的函数,广告显示效果例如以下:
版权声明:本文博客原创文章。博客,未经同意,不得转载。
Qt移动应用开发(六):QML与C++互动的更多相关文章
- Qt移动应用开发(八):实现跨平台的QML和OpenGL混合渲染
Qt移动应用开发(八):实现跨平台的QML和OpenGL混合渲染 上一篇文章讲到了利用C++这个桥梁,我们实现了QML和Java的交互.Qt 5大力推崇的QML/JS开发,让轻量.高速开发的QML/J ...
- 【Qt编程】基于Qt的词典开发系列<六>--界面美化设计
本文讲一讲界面设计,作品要面向用户,界面设计的好坏直接影响到用户的体验.现在的窗口设计基本都是扁平化的,你可以从window XP与window 8的窗口可以明显感觉出来.当然除了窗口本身的效果,窗口 ...
- Qt for Android开发环境搭建及测试过程记录
最近学习了Qt的QML编程技术,感觉相较于以前的QtGUI来说更方便一些,使用QML可以将界面与业务逻辑解耦,便于开发. QML支持跨平台,包括支持Android平台,因此可以使用Qt的QML进行An ...
- Qt 学习之路:QML 和 QtQuick 2
前面我们已经了解了 Qt 的一部分内容.这部分内容全部集中在 C++ 方面.也就是说,至今为止我们的程序都是使用 C++ 语言完成的.这在 Qt 5 之前的版本中是唯一的途径.不过,自从 Qt 5 开 ...
- Qt for Android 开发大坑
Qt for Android 开发大坑 作者: qyvlik Qt 5.5.1 这里说一说比較常见的 Qt 开发安卓的大坑. 希望同学们不要做无谓的挣扎,跳过这些坑. 输入框 首当其冲的是输入框,Qt ...
- Qt移动应用开发(二):使用动画框架
Qt移动应用开发(二):使用动画框架 上一篇博客介绍了怎样使用Qt的QML来对屏幕分辨率大小进行适应,其实,不同分辨率的适应是一个很棘手的问题,除了分辨率不同外,宽高比(aspect ratio)也不 ...
- Qt移动应用开发(一):适配不同的屏幕
Qt移动应用开发(一):适配不同的屏幕 到眼下为止.Qt5.3已经出现非常长一段时间了.而且已经有一些应用使用Qt进行构建了.我自己也完毕了第一款使用Qt构建的手机游戏<吃药了>.那么接下 ...
- 如何配置一个绿色化的 Qt for Windows 开发环境(有.bat脚本,亲测好用) good
安装 QtCreator for Windows 其实是很简单的,不过,我一向讨厌什么软件都得弄个安装程序,我希望我所安装的这个 Qt 可以是绿色的.便携的,如果无法实现,至少让这个 Qt 可以在新系 ...
- 快速全面了解QT软件界面开发技术
快速全面了解QT软件界面开发技术 目录 前言 一. 学习QT可能的目的是什么? 只想体验一下QT? 当前的项目选择了用QT. 为将来做QT技术储备. 二. QT的核心技术优势是什么? QT在软 ...
随机推荐
- js进阶 11-21 纯css实现选项卡
js进阶 11-21 纯css实现选项卡 一.总结 一句话总结:核心原理,a标签的锚点效果+父div限宽+多的部分隐藏. 1.如何实现a标签的锚点效果? href属性找到对应的位置就好,和选择器一样, ...
- mac nginx php-fpm
再一次被困在一个傻问题.由于我居然怀疑是不是mac本身就和centos的安装不一样.在一次次地排错后,最终发现.原来是我的nginx.conf的一行配置少写了一个字母.最后多亏用ls检查来定位到这个错 ...
- nyoj 949哈利波特(细节题)
哈利波特 时间限制:1000 ms | 内存限制:65535 KB 难度:3 描写叙述 Harry 新学了三种魔法.他能够用第一种魔法把 a 克的沙子变成 b 克金属,能够用另外一种魔法把 c 克 ...
- 【19.46%】【codeforces 551B】ZgukistringZ
time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...
- [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 ...
- 编写ATL控件的简单做法
作者:朱金灿 来源:http://blog.csdn.net/clever101 ATL并不像MFC库那样提供了很多的控件窗口类,因此要使用ATL的话需要自己去封装.封装的做法很简单.比如现在我需要一 ...
- ITFriend创业败局(四):菜鸟CEO的自我修养
自创业自封CEO以来,短短3个月,又经历了无数的磨练,快速成长中. 创业不同于打工,他要求你必须有全局观和综合能力,技术.市场.商务,啥都得会,还要处理各种各样的问题和矛盾. 根据个人经历,我总结了以 ...
- Tomcat的JVM经常挂掉,根据hs_err_pid23224.log这种日志文件,也没能发现具体是什么原因导致的
## A fatal error has been detected by the Java Runtime Environment:## SIGBUS (0x7) at pc=0x00007f1a ...
- Linux非图形界面安装程序
安装Linux程序的时候一般不会调取图形界面,这样输错内容,返回上一步时需要使用命令 previous ,相应的exit 与 next..在中文操作的时候,不会提示,所以要记住 在安装过程中,我们可能 ...
- Javascript中的DOM实现显示鼠标的空间位置
为了显示鼠标相对于浏览器的位置(相对于屏幕和页面类似),我们能够利用click事件,获得关于鼠标单击的事件对象event.这个事件对象里的clientX和clientY包括了鼠标的位置信息,所以我突发 ...