该文章原创于Qter开源社区(www.qter.org),作者Joey_Chan,转载请注明出处!可以到这里讨论该文章。
QML经验谈(一)
该系列教程主要讲授有关QML的实用经验,不建议完全没有Qt经验的童鞋阅读(不包括熟悉Qt C++不懂QML的)
初学QML的童鞋,也许刚刚懂得怎么用一些基本element的用法和一些动画效果,或许童鞋们会发现,QML在功能上也有很多局限性,特别是许多QT C++的功能在QML上实现不了,这时,C++仍然显得十分重要,结合QML与C++就更重要了。
1.官方文档
在QT帮助文档里面,搜索“Exposing Attributes of C++ Types to QML”即可找到权威的内容,英文好的童鞋可以直接忽略我的教程看这个。
2.案例
下面以一个简单的Qt5模板程序为例子
新建一个QtQuick2应用程序,添加一个C++类,我这里叫Test类,继承QObject,然后修改test.h头文件如下:
- #ifndef TEST_H
- #define TEST_H
- #include
- #include
- class Test : public QObject
- {
- Q_OBJECT
- public:
- explicit Test(QObject *parent = 0);
- signals:
- public slots:
- QString showString(); //这个是给QML调用的
- };
- #endif // TEST_H
复制代码 然后test.cpp的showString()函数如下:
- QString Test::showString()
- {
- return "String from C++";
- }
复制代码 再修改main.cpp文件如下:
- #include
- #include // 注意这里,没有这行会报错
- #include "qtquick2applicationviewer.h"
- #include "test.h"
- int main(int argc, char *argv[])
- {
- QGuiApplication app(argc, argv);
- Test *test = new Test(); // 刚刚新建的类
- QtQuick2ApplicationViewer viewer;
- viewer.engine()->rootContext()->setContextProperty("test", test); // 将新的类映射为QML的一个对象
- viewer.setMainQmlFile(QStringLiteral("qml/qmltest0/main.qml"));
- viewer.showExpanded();
- return app.exec();
- }
复制代码 现在回到main.qml文件,修改如下
- import QtQuick 2.0
- Rectangle {
- width: 360
- height: 360
- Text {
- id: title
- text: qsTr("Hello World")
- anchors.centerIn: parent
- }
- MouseArea {
- anchors.fill: parent
- onClicked: {
- title.text = test.showString() //将上面的标题改为前面c++写入的字符串
- }
- }
- }
复制代码 点“运行”,点一下界面就有效果了,懒得截图
3. 进阶
前面的例子示范了如果使用QML操控C++,但是反过来行不行呢? (不行的话我写出来干嘛)
来到test.h,修改如下:
- #ifndef TEST_H
- #define TEST_H
- #include
- #include
- class Test : public QObject
- {
- Q_OBJECT
- public:
- explicit Test(QObject *parent = 0);
- signals:
- void callQml(QString msg); // 这个信号是连接QML的关键,第一个字母必须小写
- public slots:
- QString showString();
- void callQmlSlot(); // 这个只是辅助发送信号的,非必要
- };
- #endif // TEST_H
复制代码 再来到test.cpp文件,修改如下:
- #include "test.h"
- Test::Test(QObject *parent) :
- QObject(parent)
- {
- QTimer::singleShot(3000, this, SLOT(callQmlSlot())); // 用计时器来激活信号
- }
- QString Test::showString()
- {
- return "String from C++";
- }
- void Test::callQmlSlot()
- {
- emit this->callQml("call from C++"); // 计时器会启动这个槽函数,从而发送信号
- }
复制代码 最后就是main.qml了,修改如下
- import QtQuick 2.0
- Rectangle {
- width: 360
- height: 360
- Text {
- id: title
- text: qsTr("Hello World")
- anchors.centerIn: parent
- }
- MouseArea {
- anchors.fill: parent
- onClicked: {
- title.text = test.showString()
- }
- }
- Connections { // 关键:Connections就是专门用来获取qml对象的信号的,这个test类已经被映射为qml对象了
- target: test // 目标对象
- onCallQml: { // 接收信号的名字,注意前面有个on,信号名第一个字母要大写
- title.text = msg // 更换标题
- }
- }
- }
复制代码 然后,点运行,效果会自动出来,我也懒得截图了
|