如何选择C++qt5与qml交互互的两种方式

13256人阅读
Meego(30)
&&&&&&&&& Qt Quick 是一种高级用户界面技术,使用它可轻松地创建供移动和嵌入式设备使用的动态触摸式界面和轻量级应用程序。三种全新的技术共同构成了 Qt Quick 用户界面创建工具包:一个改进的Qt Creator IDE、一种新增的简便易学的语言 (QML) 和一个新加入 Qt 库中名为 QtDeclarative 的模块即Qt Declarative UI,这些使得 Qt 更加便于不熟悉 C++ 的开发人员和设计人员使用。
&&&&&&&&& 研究了几天QML,我想编程人员最关心的还是QML怎样与C++ Application交互了。发现网上QT中文资料很少,唉,只能参照官网文档:
一、QML引用C++对象
//main cpp#include &QApplication&&#include &QDeclarativeView&&#include &QDeclarativeContext&&int main(int argc, char *argv[])&{&&&& QApplication app(argc, argv);&&&& QDeclarativeV&&&& QDeclarativeContext *context = view.rootContext();&&&& context-&setContextProperty("backgroundColor", QColor(Qt::yellow));&&&& view.setSource(QUrl::fromLocalFile("main.qml"));&&&& view.show();&&&& return app.exec();&}//main.qml&import Qt 4.7&Rectangle {&&&& width: 300&&&& height: 300&&&& color: backgroundColor&&&& Text {&&&&&&&& anchors.centerIn: parent&&&&&&&& text: "Hello Yellow World!"&&&& }&}对于C++中自定义的类:
//main cpp#include &QApplication&&#include &QDeclarativeView&&#include &QDeclarativeContext&
&int main(int argc, char *argv[])&{&&&& QApplication app(argc, argv);&&&& QDeclarativeV&&&& view.rootContext()-&setContextProperty("palette", new CustomPalette);&&&& view.setSource(QUrl::fromLocalFile("main.qml"));&&&& view.show();&&&& return app.exec();&}
//main.qml
&import Qt 4.7&Rectangle {&&&& width: 240&&&& height: 320&&&& color: palette.background //调用C++的类&&&& Text {&&&&&&&& anchors.centerIn: parent&&&&&&&& color: palette.text&&&&&&&& text: "Click me to change color!"&&&& }&&&& MouseArea {&&&&&&&& anchors.fill: parent&&&&&&&& onClicked: {&&&&&&&&&&&& palette.text = "blue";&&&&&&&& }&&&& }&}
二、QML,C++方法相互调用
//numbercount.h
#ifndef NumberCount_H#define NumberCount_H#include &QObject&#include &QVariant&class NumberCount : public QObject{&&& Q_OBJECTpublic:&&& explicit NumberCount(QObject *parent = 0);&&& Q_INVOKABLE int getTotal();signals:&&& void resetData(QVariant num);//用于调用qml的javascript 方法public slots:&&& int incre();&&& int decre();&&& void reset(int num);private:&&&&&&};#endif // NumberCount_H
//==========================================================
//NumberCount.cpp
#include "numbercount.h"#include &QDebug&NumberCount::NumberCount(QObject *parent) :&&& QObject(parent){&&& this-&total = 100;}int NumberCount::incre(){&&& qDebug()&&"count=: "&& ++&&& count++;&&&}int NumberCount::decre(){&& qDebug()&&"count=: "&& --&& count--;&&}void NumberCount::reset(int num){&&& this-&total =&&& count = 0;&&& emit resetData(QVariant(num));//调用qml的javascript 方法}int NumberCount::getTotal(){&&&}
//==========================================================
//numbercount.qml
import Qt 4.7Rectangle {&&& //signal resetD&&& function resetData(text){&&&&&&& console.log("javascript resetData方法被C++调用!");&&&&&&& btn_decre.text =& "增加&font color='#0000FF'&(0)&/font&";&&&&&&& btn_incre.text = "减少&font color='#0000FF'&(0)&/font&";&&&&&&& txt_show.text = "总数:" +&&&&&&& txt_reset.text = "总数重置为:"+&&& }&&& width: 300&&& height: 300&&& radius: 20&&& anchors.fill: parent&&& Text {&&&&&&& id: txt_show&&&&&&& x: 150&&&&&&& y: 0&&&&&&& text : "总数:" + numberCount.getTotal(100);&&& }&&& Rectangle{&&&&&&& x:100&&&&&&& y:50&&&&&&& width: 80&&&&&&& height: 25&&&&&&& Image{&&&&&&&&&&& anchors.fill: parent&&&&&&&&&&& width:parent.width&&&&&&&&&&& height: parent.width&&&&&&&&&&& source: "/ui/images/button.png"&&&&&&& }&&&&&&& Text {&&&&&&&&&&& id: btn_incre&&&&&&&&&&& anchors.centerIn: parent&&&&&&&&&&& text: "增加"&&&&&&&&&&& MouseArea{&&&&&&&&&&&&&&& anchors.fill: parent&&&&&&&&&&&&&&& onClicked: {&&&&&&&&&&&&&&&&&& var num = numberCount.incre();&&&&&&&&&&&&&&&&&& parent.text =& "增加&font color='#0000FF'&(" + num +")&/font&";&&&&&&&&&&&&&&&&&& btn_decre.text = "减少&font color='#0000FF'&("+ num+")&/font&";&&&&&&&&&&&&&&&&&& txt_show.text = "总数:" + numberCount.getTotal();&&&&&&&&&&&&&&& }&&&&&&&&&&& }&&&&&&& }&&& }&&& Rectangle{&&&&&&& x:100&&&&&&& y:100&&&&&&& width: 80&&&&&&& height: 25&&&&&&& Image{&&&&&&&&&&& anchors.fill: parent&&&&&&&&&&& width:parent.width&&&&&&&&&&& height: parent.width&&&&&&&&&&& source: "/ui/images/button.png"&&&&&&& }&&&&&&& Text {&&&&&&&&&&& id: btn_decre&&&&&&&&&&& anchors.centerIn: parent&&&&&&&&&&& text: "减少"&&&&&&&&&&& MouseArea{&&&&&&&&&&&&&&& anchors.fill: parent&&&&&&&&&&&&&&& onClicked: {&&&&&&&&&&&&&&&&&&& var num = numberCount.decre();&&&&&&&&&&&&&&&&&&& parent.text =& "减少&font color='#0000FF'&(" + num +")&/font&";&&&&&&&&&&&&&&&&&&& btn_incre.text = "增加&font color='#0000FF'&("+ num+")&/font&";&&&&&&&&&&&&&&&&&&& txt_show.text = "总数:" + numberCount.getTotal();&&&&&&&&&&&&&&& }&&&&&&&&&&& }&&&&&&& }&&& }&&& Rectangle{&&&&&&& x:100&&&&&&& y:150&&&&&&& width: 80&&&&&&& height: 25&&&&&&& Image{&&&&&&&&&&& anchors.fill: parent&&&&&&&&&&& width:parent.width&&&&&&&&&&& height: parent.width&&&&&&&&&&& source: "/ui/images/button.png"&&&&&&& }&&&&&&& Text {&&&&&&&&&&& id: btn_show&&&&&&&&&&& anchors.centerIn: parent&&&&&&&&&&& text: "重置总数"&&&&&&&&&&& MouseArea{&&&&&&&&&&&&&&& anchors.fill: parent&&&&&&&&&&&&&&& onClicked: {&&&&&&&&&&&&&&&&&&& numberCount.reset(200);&&&&&&&&&&&&&&& }&&&&&&&&&&& }&&&&&&& }&&& }&&& Text {&&&&&&& id: txt_reset&&&&&&& x: 100&&&&&&& y: 200&&&&&&& color: "#12ff12"&&& }}
//==========================================================
&RCC&&&& &qresource prefix="/ui"&&&&&&&& &file alias="qml/qml_main"&Auto_Order_UI.qml&/file&&&&&&&& &file&images/Alert_09.png&/file&&&&&&&& &file&images/Alert_10.png&/file&&&&&&&& &file&images/Alert_11.png&/file&&&&&&&& &file&images/Alert_12.png&/file&&&&&&&& &file&images/Alert_13.png&/file&&&&&&&& &file&images/Alert_14.png&/file&&&&&&&& &file&images/Alert_15.png&/file&&&&&&&& &file&images/Alert_16.png&/file&&&&&&&& &file&images/carmageddon2.png&/file&&&&&&&& &file&images/counter-strike.png&/file&&&&&&&& &file&images/X3.png&/file&&&&&&&& &file alias="qml/qml_sw"&sw.qml&/file&&&&&&&& &file&images/button.png&/file&&&& &/qresource&&/RCC&
//==========================================================
//main.cpp
#include &QtGui/QApplication&#include "mainwindow.h"#include &QtDeclarative/QDeclarativeView&#include &QtDeclarative/QDeclarativeComponent&#include &QtDeclarative/QDeclarativeItem&#include &QtDeclarative/QDeclarativeEngine&#include &QtDeclarative/QDeclarativeContext&#include "numbercount.h"int main(int argc, char *argv[]){&&& QApplication a(argc, argv);&&& NumberCount *numberCount = new NumberCount();&&& QDeclarativeContext *context = view.rootContext();&&& context-&setContextProperty("numberCount",numberCount);//注册C++对象到qml&&& view.setSource(QUrl("qrc:/ui/qml/qml_sw"));&&& QObject *rootObject = dynamic_cast&QObject*&(view.rootObject());&&& QObject::connect(numberCount, SIGNAL(resetData(QVariant)), rootObject, SLOT(resetData(QVariant)));//将C++信号与QML槽关联&&& view.show();&&& return a.exec();}
官方文档:
It is possible to call methods of&
& derived types by either exposing the methods as public slots, or by marking the methods&
也就是说 getTotal()和incre()都能在QML中访问。
运行界面:
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:603653次
积分:6230
积分:6230
排名:第2869名
原创:112篇
评论:218条
(2)(7)(4)(3)(1)(1)(2)(1)(1)(1)(1)(5)(1)(10)(3)(1)(6)(1)(1)(1)(4)(1)(4)(6)(3)(2)(4)(4)(15)(5)(3)(4)(8)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/
&&&&&& 首先一个较为简单的方法就是注册上下文属性(Context Property),让QML访问C++的变量。代码如下:
#include &QApplication&
#include &QQmlApplicationEngine&
#include &QQmlContext&
int main(int argc, char *argv[])
QApplication app(argc, argv);
QQmlApplicationE
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
title: qsTr(&文件&)
text: qsTr(&退出&)
onTriggered: Qt.quit( );
text: qsTr(&本例用来测试QML和C++的交互&)
anchors.right: parent.right
anchors.bottom: parent.bottom
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_PROPERTY( int rating READ rating )
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_R }
#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&,
// 统一资源标识符
&CPlusPlusType& );
// QML类名称
QQmlApplicationE
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
title: qsTr(&文件&)
text: qsTr(&退出&)
onTriggered: Qt.quit( );
text: qsTr(&本例用来测试QML和C++的交互&)
anchors.right: parent.right
anchors.bottom: parent.bottom
CPlusPlusType
id: theType
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_PROPERTY( int rating READ rating )
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_R }
#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 CPlusPlusS
int main(int argc, char *argv[])
QApplication app(argc, argv);
// 首先注册一下单例
qmlRegisterSingletonType&CPlusPlusSingleton&(
&CPlusPlus.Test&,
// 统一资源标识符
&CPlusPlusSingleton&,
// 单例名称
CPlusPlusSingletonRegisterFunc );
QQmlApplicationE
engine.load(QUrl(QStringLiteral(&qrc:///main.qml&)));
return app.exec();
就这样,C++的部分就完成了。接下来在QML中就很简单了:
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
title: qsTr(&文件&)
text: qsTr(&退出&)
onTriggered: Qt.quit( );
text: qsTr(&本例用来测试QML和C++的交互&)
anchors.right: parent.right
anchors.bottom: parent.bottom
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++的函数,广告显示效果如下:
本文参加了CSDN博文大赛,请大家支持我,为我投一票![Qt Dream]Qt 在线技术交流之C++ 与 QML 交互 - QTCN开发网 - Powered by phpwind
查看完整版本: [--
[Qt Dream]Qt 在线技术交流之C++ 与 QML 交互
本周六晚七点半开讲内容:C++ 与 QML 交互地点上海Qt开发联盟 (QQ群号:) 群视频。如果您想围观的话,那么也可以进入全民TV直播()来观摩。以下为本次交流会大纲:QML 与 C++ 的交互有人说 QML 与 C++ 的交互太麻烦了,由于 QML 本身是面向对象的,所以交互起来依赖于 Qt 本身的元对象系统,显得十分笨重。但是仔细研究就会明白这样做的意义了。QML 与 C++ 的数据交互Qt TypeQML Basic Typeboolboolunsigned int, intintdoubledoublefloat, qrealrealQStringstringQUrlurlQColorcolorQFontfontQDatedateQPoint, QPointFpointQSize, QSizeFsizeQRect, QRectFrectQMatrix4x4matrix4x4QQuaternionquaternionQVector2D, QVector3D, QVector4Dvector2d, vector3d, vector4dQ_ENUMenumerationQVariant,QVariantMap,QVariantList,QJSValuevar,jsObject,jsArray,variantQJsonValue,QJsonObject, QJsonArrayvar, JSONObject带有 Q_GADGET 声明的类varQObject*idQQmlListPropertylist经测试,QVariant,QVariantMap,QVariantList 可以处理var类型的属性。另外可以将 qml 对象的 id 传入,C++参数是 QObject*。如果要将一个数组从 C++ 传给 QML,最好使用 QJsonArray,或者QList&QString&,QList&QVariant&,QList&QJSValue&,QQmlListProperty&T&。注意,不同 QJSEngine 之间的 QJSValue 不同互相使用。QML 调用 C++ 对象方法全局单例qmlRegisterSingleton注册的单例有两类,一类 QObject*,一类 QJSValue。QQmlContext::setContextProperty(QString, QObject*);这个注册到上下文时要注意他的生命还未开始。注册新类型到 QMLQObjectQQuickItemQQuickPaintItemQAbstractItemModel推荐使用 QAbstractListModel,省时间。如下诉代码:int rowCount(const QModelIndex &parent)QVariant data(const QModelIndex &index, int role)QHash&int, QByteArray& roleNames() const;&&&&enum Roles{NameRole = Qt::UserRole + 1,AgeRole};int rowCount(const QModelIndex &parent)QVariant data(const QModelIndex &index, int role)QHash&int, QByteArray& roleNames() const;int TestModel::rowCount(const QModelIndex &parent) const{Q_UNUSED(parent)return m_datas.length();}QVariant TestModel::data(const QModelIndex &index, int role) const{if (!index.isValid() || index.row() & 0)return QVariant();if (index.row() &= m_datas.count()) {qWarning() && &SatelliteModel: Index out of bound&;return QVariant();}const Dao &dao = m_datas.at(index.row());switch (role){case NameRole:return dao.name();case AgeRole:return dao.age();default:break;}return QVariant();}QHash&int, QByteArray& TestModel::roleNames() const{QHash&int, QByteArray& roleNroleNames.insert(NameRole, &NameRole&);roleNames.insert(AgeRole, &AgeRole&);return roleN}Q_GADGET使用 Q_GADGET 可以支持注册枚举,属性,Q_INVOKABLE。但是不支持信号和槽。C++ 调用 QML 对象方法将 qml 对象的 id 以 QObject* 的方式进行传参在 C++ 代码中主动捕获 qml 对象属性系统invokeMethod具体两个实例。qml 中的多线程。qml 中的文件读写和网络
:[表情]  [表情]  [表情]  [表情]  [表情]  ( 17:13) 谢谢支持,欢迎围观。
高清重置版已经上线
不错,支持一个!!对了C++和QML结合还有很多例子,尽在Qt帮助文档。
楼主: &&&&qml 怎么用 c++申明的枚举类型?
&&学习学习
查看完整版本: [--
Powered by
Gzip disabled后使用快捷导航没有帐号?
您尚未登录,请登录后浏览更多内容!
查看: 10837|回复: 4
在线时间459 小时帖子精华10Qter豆4891 贡献34 毅力1102 注册时间最后登录
Qter豆4891
该文章原创于Qter开源社区(),作者Joey_Chan,转载请注明出处!
QML经验谈(二) 关于动态QML组件的几种用法
该系列教程主要讲授有关QML的实用经验,不建议完全没有Qt经验的童鞋阅读(不包括熟悉Qt C++不懂QML的)
初学QML的童鞋,也许刚刚懂得怎么用一些基本element的用法和一些动画效果,或许童鞋们会发现,QML除了显示源码上的那些控件外,能不能按照逻辑动态增加/减少一些东西呢?比如鼠标点一下多一个气球,再点一下气球就消失,总不可能先在代码里面写上几百上千个气球的代码再一个个去显示吧& &(;???Д??`)
1.官方文档
在QT帮助文档里面,搜索“Dynamic QML Object Creation from JavaScript”即可找到我下文要写的大部分内容,英文好的童鞋可以直接忽略我的教程看这个。
2.几种常用动态qml方法
相信大部分童鞋都知道什么是MVC,概念我不说了,在qml这里其实就是listview,gridview这类东东。我把这类摆第一位主要因为这种最常用到也是最容易学的。
来一段示例代码,无关的属性什么的我就不详细写了,多看看官方文档:
Rectangle {
& & color: &blue&
& & MouseArea { onClicked: { modelMVC.add( { /*随便加点东东*/ } ) } }& && && && &&&// 每点一次这个就可以动态加东西
}
Listview {& && && && && && && && && && && && && && && & // 这个就是V
& & id: listviewMVC
& & model: modelMVC& && && && && && & // 这个就是M
& & delegate: delegateMVC& && && &&&// 这个就是C
& &
& & Component {
& && &&&id: delegateMVC
& && &&&Rectangle {
& && && && &color: &red&
& && && && &MouseArea { anchors.fill: onClicked: { modelMVC.remove(index) } }& && && && && && &// 每点一次这个就可以去掉自己
& && &&&}
& & }
& &
& & Listmodel {
& && &&&id: modelMVC
& & }
}
复制代码实际运行效果,listview初始化后就是一个列表,列表的多少完全由model控制,这样动态的添加和删除就只需要操作这个model就行了,上面例子就是add和remove两个函数而已。
2.2 Loader
确切来说Loader和MVC一样不能算完全动态的qml,因为都需要一个静态的外壳,MVC的外壳就好理解了,那Loader又是什么东东?
如果等效成C++来看,Loader就类似一个指针,如果只写了一个Loader在qml里面,其实就相当于一个空指针,没意义。如果想要它有意义,只需要指定内容就行了,类似C++的new。
下面是一个空Loader例子:
Loader {
& & id: loader
& & source: &&
& & sourceComponent: undefined
}
复制代码这个空Loader除了占地方外,没有任何意义,因为就相当于一个空指针。
这里稍微解释一下Loader的用法,具体请查看文档:
source里面加入qml文件的地址就能加载这个qml文件的内容;
sourceComponent指定某个qml代码片段,一般指Component类型;
以上两者不能同时使用
当加入内容后,代码如下:
Loader {
& & id: loader
& & // 这里最好先设定好大小,不然可能会因为大小没定而不显示东西
& & source: &TestComponent.qml&
}
复制代码Loader就会把TestComponent.qml的内容都加载进内存中并显示出来,这里要注意的是,Loader里面的东西和外面是半隔离状态的,就是外面只能看到Loader外壳,反之透明。如果需要访问Loader里面的内容需要使用Loader.item来访问。
来一小段代码示范
function testLoader () {
& & //先访问loader内容,然后清空loader
& & print(loader.item.text)& && &//我乱编的属性
& & loader.source = &&& && && && &&&//清空的方法很多,文档有写
}
复制代码2.3 Dynamic QML Object Creation from JavaScript&&(来自JS的动态qml对象加载)
详情可以直接在文档中搜这段英文,英文好的童鞋可以跳过我这段。
这种方法相对于前两种,是真正的完全动态生成qml对象,用法也很灵活,当然代价也是不太容易学会。
先介绍如何创建动态的qml对象:
准备好一个组件:
import QtQuick 2.0
Rectangle { width: 80; height: 50; color: &red& }
复制代码然后是一段js代码,用来创建qml对象
function createSpriteObjects() {
& & component = Qt.createComponent(&Sprite.qml&);& && && && &&&//&&这个可以理解为预加载qml文件
& & if (component.status == Component.Ready)
& && &&&finishCreation();
& & else
& && &&&component.statusChanged.connect(finishCreation);& && && &&&// c++里面的connect在qml里面的用法之一
}
function finishCreation() {
& & if (component.status == Component.Ready) {
& && &&&sprite = component.createObject(appWindow, {&x&: 100, &y&: 100});& && && && &//&&这个才是关键地方, 在内存中生成qml对象
& && &&&if (sprite == null) {
& && && && &// Error Handling
& && && && &console.log(&Error creating object&);
& && &&&}
& & } else if (component.status == Component.Error) {
& && &&&// Error Handling
& && &&&console.log(&Error loading component:&, component.errorString());
& & }
}
复制代码只要调用上面的js代码就能随时随地创建qml对象了
import QtQuick 2.0
import &componentCreation.js& as MyScript
Rectangle {
& & id: appWindow
& & width: 300; height: 300
& & Component.onCompleted: MyScript.createSpriteObjects();& && && && && &//&&这里调用上面的js代码段
}
复制代码同样的稍微再改一下就能用鼠标来控制创建
import QtQuick 2.0
import &componentCreation.js& as MyScript
Rectangle {
& & id: appWindow
& & width: 300; height: 300
& & MouseArea {
& && &&&anchors.fill: parent
& && &&&onClicked: MyScript.createSpriteObjects();& && && && && &//&&这里调用上面的js代码段
& & }
}
复制代码那么如果我想让创建的qml对象消失呢?很简单,调用destroy函数即可。这里回到上面的qml文件,改成下面
import QtQuick 2.0
Rectangle {
& & width: 80; height: 50; color: &red&
& & MouseArea {
& && &&&anchors.fill: parent
& && &&&onClicked: parent.destroy()& && && && &&&//&&必须给根对象用这个destroy函数,不然会出错
& & }
}
复制代码到这里,qml动态创建和销毁基本就这样了,其实这个方法也是官方极力推荐的,建议大家多用。
有童鞋看到这里可能有疑问,这些动态的对象没有id我怎么去操作啊?——没错,qml里面非静态的对象基本上没有id可言,操作这些对象就要用到qt特有的功能——signal & slot
继续用上面的代码:
import QtQuick 2.0
Rectangle {
& & width: 80; height: 50; color: &red&
& & signal test()& && && & // 声明一个信号
& &
& & Component.onCompleted: test.connect(/* 随便指定一个外部函数即可,如appWindow.slot,注意这里不需要加括号 */)& && && && && &
& & //&&用法是&&&对象名(省略的话就是自己)&. &信号名&.connect(&普通函数名&)
& &
& & MouseArea {
& && &&&anchors.fill: parent
& && &&&onClicked: parent.destroy()& && && && &&&//&&必须给根对象用这个destroy函数,不然会出错
& & }
}
复制代码同样道理,外面的信号也能这样连到动态对象的函数
注:方法2.3还有另一种我个人觉得不怎么好用的创建qml方式,如下:
var newObject = Qt.createQmlObject('import QtQuick 2.0; Rectangle {color: &red&; width: 20; height: 20}',
& & parentItem, &dynamicSnippet1&);
复制代码本次教程暂告一段落,欢迎高手们拍砖。 ?(????)& &(┙&∧&)┙へ┻┻
对我帮助很大!
总评分:&人气 + 2&
在线时间393 小时帖子精华4Qter豆3132 贡献143 毅力566 注册时间最后登录
Qter豆3132
嗯。总结的不错。
在线时间459 小时帖子精华10Qter豆4891 贡献34 毅力1102 注册时间最后登录
Qter豆4891
yafeilinux 发表于
嗯。总结的不错。
( ??`)σ)Д`)
在线时间202 小时帖子精华1Qter豆1827 贡献45 毅力551 注册时间最后登录
Qter3级会员, 积分 596, 距离下一级还需 204 积分
Qter豆1827
我就喜欢看大神讲课,已搬凳子坐下听课。
在线时间459 小时帖子精华10Qter豆4891 贡献34 毅力1102 注册时间最后登录
Qter豆4891
sywh 发表于
我就喜欢看大神讲课,已搬凳子坐下听课。
o(///▽///)q
注册账号后积极上传头像的会员
坚持登陆,持之以恒!
积极发帖的会员
Powered by
X2.5. Theme By

我要回帖

更多关于 qml与qt交互 的文章

 

随机推荐