QML和C++代码之间互相调用及参数之间的转换
2015-09-09 10:42
507 查看
我们知道, 在QML中我们可以很容易地调用C++代码. 同样, 我们可以在C++中调用放在QML中的Javascript代码. 由于存在函数/方法之间的调用, 数据类型之间的转换是比不可少的.在今天的文章中,我们来简单地介绍一下如何互相调用及一些类型的转换.
我们可以在文章"QML Basic Types"及"Data Type Conversion Between QML
and C++"中得到更多的信息.
在上面的代码中,我们可以看到.我们通过如下的方法:
调用一个在Main.qml中定义的一个叫做readValues()的Javascript方法:
上面的输出结果为:
我们可以看出来QVariantList被映射到Javascript的Array,而QVariantMap被映射到我们Javacript中的Object.这个概念是非常重要的.我们可以在"QML Basic Types"中找到更多的关于类型之间的映射.
同样,我们可以在Javascript中调用一个定义在C++代码中的方法,并把我们所需要的参数传人,进而得到解析.
这里myclass是定义在C++中的一个类的实例.我们调用callingFromQml()方法:
这里cmyclass.h定义如下:
注意这里的Q_INVOKABLE,表明它是可以在QML中可以调用的.更多关于QML调用调用C++的介绍,请参阅文章"Exposing Attributes of C++ Types to QML".一般来说,QML可以调用C++ QObject类的如下成员:
Properties
Methods (providing they are public slots or flagged with Q_INVOKABLE)
Signals
它的输出为:
整个应用的界面为:
整个项目的源码在:https://github.com/liu-xiao-guo/dataconversion
我们可以在文章"QML Basic Types"及"Data Type Conversion Between QML
and C++"中得到更多的信息.
如何从C++中调用QML中的Javascript代码
main.cpp
#include <QGuiApplication> #include <QQmlApplicationEngine> #include <QQuickView> #include <QDate> #include <QMetaObject> #include <QVariant> #include <QArgument> #include <QQuickItem> #include <QQmlContext> #include "cmyclass.h" int main(int argc, char *argv[]) { QGuiApplication app(argc, argv); QQuickView view; view.setSource(QUrl(QStringLiteral("qrc:///Main.qml"))); view.setResizeMode(QQuickView::SizeRootObjectToView); QVariantList list; list << 10 << QColor(Qt::green) << "bottles"; QVariantMap map; map.insert("language", "QML"); map.insert("released", QDate(2010, 9, 21)); QMetaObject::invokeMethod(view.rootObject(), "readValues", Q_ARG(QVariant, QVariant::fromValue(list)), Q_ARG(QVariant, QVariant::fromValue(map))); MyClass myclass; view.rootContext()->setContextProperty("myclass", &myclass); view.show(); return app.exec(); }
在上面的代码中,我们可以看到.我们通过如下的方法:
QMetaObject::invokeMethod(view.rootObject(), "readValues", Q_ARG(QVariant, QVariant::fromValue(list)), Q_ARG(QVariant, QVariant::fromValue(map)));
调用一个在Main.qml中定义的一个叫做readValues()的Javascript方法:
import QtQuick 2.0 import Ubuntu.Components 1.1 /*! \brief MainView with a Label and Button elements. */ MainView { // objectName for functional testing purposes (autopilot-qt5) objectName: "mainView" // Note! applicationName needs to match the "name" field of the click manifest applicationName: "dataconversion.liu-xiao-guo" /* This property enables the application to change orientation when the device is rotated. The default is false. */ //automaticOrientation: true // Removes the old toolbar and enables new features of the new header. useDeprecatedToolbar: false width: units.gu(60) height: units.gu(85) function readValues(anArray, anObject) { for (var i = 0; i < anArray.length; i++ ) console.log("Array item:", anArray[ i ]) for (var prop in anObject) { console.log("Object item:", prop, "=", anObject[prop]) } } Page { title: i18n.tr("dataconversion") Button { anchors.centerIn: parent text: "Call C++ to pass array and object" onClicked: { var i = { "from" : "xiaoguo.liu@company.com", "to" : "y@mail.com", "message" : "This is teriffic!" }; var j = ["Saab", "Volvo", "BMW"]; myclass.callingFromQml(j, i); } } } }
上面的输出结果为:
qml: Array item: 10 qml: Array item: #00ff00 qml: Array item: bottles qml: Object item: language = QML qml: Object item: released = 周二 9月 21 00:00:00 2010 GMT+0800
我们可以看出来QVariantList被映射到Javascript的Array,而QVariantMap被映射到我们Javacript中的Object.这个概念是非常重要的.我们可以在"QML Basic Types"中找到更多的关于类型之间的映射.
同样,我们可以在Javascript中调用一个定义在C++代码中的方法,并把我们所需要的参数传人,进而得到解析.
Button { anchors.centerIn: parent text: "Call C++ to pass array and object" onClicked: { var i = { "from" : "xiaoguo.liu@company.com", "to" : "y@mail.com", "message" : "This is teriffic!" }; var j = ["Saab", "Volvo", "BMW"]; myclass.callingFromQml(j, i); } }
这里myclass是定义在C++中的一个类的实例.我们调用callingFromQml()方法:
void MyClass::callingFromQml(QVariantList list, QVariantMap map) { qDebug() << "It is called from QML!"; int count = list.count(); qDebug() << "count: " << list.count(); qDebug() << "The array values are: "; for ( int i = 0; i < count; i++ ) { QString value = list[i].toString(); qDebug() << "value: " << value; } qDebug() << "The object values are: "; qDebug() << "map.from" << map["from"].toString(); qDebug() << "map.to" << map["to"].toString(); qDebug() << "map.message" << map["message"].toString(); }
这里cmyclass.h定义如下:
cmyclass.h
#ifndef CMYCLASS_H #define CMYCLASS_H #include <QObject> #include <QVariantList> #include <QVariantMap> class MyClass : public QObject { Q_OBJECT public: explicit MyClass(QObject *parent = 0); Q_INVOKABLE void callingFromQml(QVariantList list, QVariantMap map); signals: public slots: }; #endif // CMYCLASS_H
注意这里的Q_INVOKABLE,表明它是可以在QML中可以调用的.更多关于QML调用调用C++的介绍,请参阅文章"Exposing Attributes of C++ Types to QML".一般来说,QML可以调用C++ QObject类的如下成员:
Properties
Methods (providing they are public slots or flagged with Q_INVOKABLE)
Signals
它的输出为:
It is called from QML! count: 3 The array values are: value: "Saab" value: "Volvo" value: "BMW" The object values are: map.from "xiaoguo.liu@company.com" map.to "y@mail.com" map.message "This is teriffic!"
整个应用的界面为:
整个项目的源码在:https://github.com/liu-xiao-guo/dataconversion
相关文章推荐
- VS2005 C++ 项目怎样添加“库目录”和“包含目录”
- 转:值得推荐的C/C++框架和库 (真的很强大)
- C++函数模板template
- c++ stl 之vector浅析
- 转:值得推荐的C/C++框架和库 (真的很强大)
- 一些程序函数 C++语言,找数组中弟第K大的数和自己写的子符串截取函数
- C++ primer 笔记
- c++ ActiveX基础1:使用VS2010创建MFC ActiveX工程项目
- c++必须在类初始化列表中初始化的几种情况
- C++--------------------------------------Map的基础用法
- C++学习首页
- 日历查询
- C++虚函数
- C++语言的设计与演化&nbsp;&nbsp;读书笔记三
- C++语言的设计与演化&nbsp;读书笔记二
- C++语言的设计与演化&nbsp;读书笔记一
- C++ 优先队列的简单实现
- C++语言的设计与演化 读书笔记三
- C++语言的设计与演化 读书笔记一
- C++语言的设计与演化 读书笔记二