赞
踩
QML被设计为可通过C ++代码轻松扩展。 Qt QML模块中的类允许从C ++加载和处理QML对象,并且QML引擎与Qt的元对象系统集成的性质使C ++功能可以直接从QML调用。 这允许开发混合应用程序,该混合应用程序将QML,JavaScript和C ++代码混合在一起实现。
为了向QML提供一些C ++数据或功能,必须从QObject派生的类中使它可用。 将C ++类型的属性公开给QML后,由于QML引擎已与元对象系统集成,因此可以从QML访问任何QObject派生类的属性,方法和信号。
可以通过多种方式将C++功能类公开给QML。
QML引擎允许实例化和非实例化类型的注册。
注册可实例化的类型可使C ++类用作QML对象类型的定义,从而允许将其用于QML代码的对象声明中以创建此类型的对象。注册还为引擎提供了其他类型的元数据,使该类型(以及该类声明的任何枚举)可用作属性值,方法参数和返回值以及在QML和C ++之间交换的信号参数的数据类型。
任何QObject派生的C ++类都可以注册为QML对象类型的定义。
一旦在QML类型系统中注册了一个类,就可以像声明QML代码中的任何其他对象类型一样声明和实例化该类。 一旦创建了一个类实例,就可以从QML中对其进行操作。 正如将C ++类型的属性暴露给QML所解释的那样,可以从QML代码访问任何QObject派生类的属性,方法和信号。
要将QObject派生的类注册为可实例化的QML对象类型,请调用qmlRegisterType()将该类作为QML类型注册到特定的类型名称空间中。 然后,可以导入该名称空间以使用该类型。
class Message : public QObject
{
Q_OBJECT
Q_PROPERTY(QString author READ author WRITE setAuthor NOTIFY authorChanged)
Q_PROPERTY(QDateTime creationDate READ creationDate WRITE setCreationDate NOTIFY creationDateChanged)
public:
// ...
};
qmlRegisterType<Message>("com.mycompany.messaging", 1, 0, "Message");
import com.mycompany.messaging 1.0
Message {
author: "Amelie"
creationDate: new Date()
}
不需要实例化的场景
注册非实例类型方法
单例类型使属性,信号和方法可以在名称空间中公开,而无需客户端手动实例化对象实例。特别是QObject单例类型是一种提供功能或全局属性值的高效便捷的方法。
请注意,单例类型没有关联的QQmlContext,因为它们在引擎中的所有上下文之间共享。 QObject单例类型实例由QQmlEngine构造和拥有,并且在销毁引擎时将销毁。
int qmlRegisterSingletonType(const char *uri, int versionMajor, int versionMinor, const char *typeName, QJSValue (*)(QQmlEngine *, QJSEngine *) callback)
setContextProperty 是将对象暴露给 QML,一般默认就是全局单例。
Qt QML模块还提供了从C ++代码进行反向操作和操作QML对象的方法。
警告:尽管可以从C ++访问QML对象并对其进行操作,但是除了测试和原型设计目的之外,不建议使用这种方法。
#ifndef MYCLASS_H #define MYCLASS_H #include <QObject> #include <QString> class MyClass : public QObject { Q_OBJECT Q_PROPERTY(QString myString READ myString WRITE setmyString NOTIFY myStringChanged) public: explicit MyClass(QObject *parent = 0); Q_INVOKABLE QString getMyString(); signals: void myStringChanged(); public slots: void setmyString(QString aString); QString myString(); private: QString m_string; }; #endif // MYCLASS_H
若你想数据元素中的方法可以被QML直接调用有2种方法:
QML可以直接访问改数据元素的属性,该属性由QPROPERTY所申明。
//main.cpp MyClass myObj; QDeclarativeEngine *engine=viewer.engine(); QDeclarativeContext *context=engine->rootContext(); context->setContextProperty("myObjectExposeByCXProperty", &myObj); qml中可以直接使用myObjectExposeByCxProperty对象。 //mainpage.qml ... Button{ ... id:btn1 ... text: qsTr("PROPERTY") //此处调用myString为MyClass的QPROPERTY的属性不是方法,所以没有括号。 onClicked: label.text=myObjectExposeByCXProperty.myString; } ...
//main.cpp qmlRegisterType<MyClass>("RegisterMyType", 1, 0, "MyClassType"); QML中这样使用 //mainpage.qml ... import RegisterMyType 1.0 Button{ id:btn2 ... text: qsTr("INOVKABLE") //此处调用的时INVOKABLE的方法,不是属性,所以有括号。 onClicked: label.text=myclassExposeByRegType.getMyString(); } //创建对象,由于QML是解释执行的,所以放后面也没什么关系。 MyClassType { id:myclassExposeByRegType } 步骤: 1. 导入import。 2. 创建对象。 3. id直接使用。
在qml中点击按钮控件,改变其中对象的字符串,这时候在Qt C++中发送一个signal信号给qml端,qml端接收到使用signal handler响应,改变label2的值。具体代码如下。
qml中修改string的值。 //mainpage.qml Button{ id:btn3 text: qsTr("emit stringchanged signal") onClicked: myObjectExposeByCXProperty.myString="xxxxx"; } Qt C++触发信号 //myclass.cpp void MyClass::setmyString(QString aString) { if(aString==m_string) { return; } m_string=aString; emit myStringChanged(); } 连接signal handler响应 //mainpage.qml Connections { target: myObjectExposeByCXProperty onMyStringChanged:label2.text="Signal handler received" }
把你的Qt C++中的对象暴露给QML端,然后利用signals-slots 进行连接,并传递消息。
#include<QObject> class NetConnectController : public QObject { Q_OBJECT Q_PROPERTY(int status READ status WRITE setStatus NOTIFY statusChanged) public: explicit NetConnectController(QObject *parent = 0); void Ready() { emit statusChanged( m_status); } signals: void statusChanged(int aStatus); private: int status() const; void setStatus(int aStatus); private : //表示网络不同的状态 int m_status; };
..... NetConnectController netController QDeclarativeEngine * engine = viewer.engine(); (engine->rootContext())->setContextProperty("NetController",&netController); ..... 3在QML中连接Signal-slot ...... Connections { target: NetController onStatusChanged:changeStatus(aStatus)//Call JS Function } ...... 注意:上面的onStatusChanged 命名格式 “on”+"Qt C++中的signal名字"。在QML端可以直接使用Qt C++端的参数。例如上面的"aStatus"。
枚举定义不能使用typedef
Qt C++与QML混合编程(2)- QML中使用C++的枚举、结构体、列表类型的函数
1、Overview - QML and C++ Integration
2、QML与C++混合编程详解
3、Defining QML Types from C++
4、QML与C++交互
5、QT开发(六十九)——QML与C++混合编程
6、QML与Qt C++ 交互机制探讨与总结
7、good–Qt Quick 之 QML 与 C++ 混合编程详解
8、Qt C++与QML混合编程(2)- QML中使用C++的枚举、结构体、列表类型的函数
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。