QML中使用C++类的实现

      之前用Qt写过串口的小软件。STM32 IAP工具 和 用qt写的一个简单到不能在简单的上位机 。后来接触了QML,觉得传统的那种界面太那个了,写样式也麻烦。所以很早就想过用QML来为串口上位机做界面。无奈没搞懂QML到底是如何去调用C++的。百度了一堆文章,多半是翻译官方的例子。不知所云。直到最近在csdn上看到一篇文章 Qt Quick 之 QML 与 C++ 混合编程详解 ,终于有点懂了。不过,文章似乎有点长了。博客园上面也有见过,有朋友写过类似的文章。今天,总算实现了QML访问一个自定义类中的属性。故写下这篇文章。

      例子很简单,main.qml访问stringt类中的一个属性并显示其内容:m_String 

      注意:Qt版本 5.4.0 | Creater版本 3.3.0

     首先创建一个新的 Qt Quick Application-->选择controls 1.3。选择带controls的,生成的main.qml的根是ApplicationWindow 而另一种则是Window,其他的看起来没什么区别。具体要查文档咯

项目中有个MainForm.ui.qml。把他删掉。然后修改main.qml文件。

 

1 ApplicationWindow {
2     title: qsTr("Hello World")
3     width: 640
4     height: 480
5     visible: true     //显示窗口
6 
7     
8 }

然后创建一个stringt类继承QObject。如果想要让一个类可以被qml访问。这个类必须是继承QObject或其派生类。

使用宏Q_PROPERTY可以让方法被moc感知。stringt类的代码如下

 1 #ifndef STRINGT_H
 2 #define STRINGT_H
 3 
 4 #include <QObject>
 5 
 6 class stringt : public QObject
 7 {
 8     Q_OBJECT
 9     Q_PROPERTY(QString Ttext READ Ttext WRITE setTtext)
10 public:
11     explicit stringt(QObject *parent = 0);
12     ~stringt();
13 
14     QString Ttext(void) const;
15     void setTtext(const QString str);
16 signals:
17 
18 public slots:
19 
20 private:
21     QString m_String;
22 };
23 
24 #endif // STRINGT_H

上边是头文件,接下来是源文件

 1 #include "stringt.h"
 2 
 3 stringt::stringt(QObject *parent)
 4     : QObject(parent)
 5     , m_String("Text just")
 6 {
 7 
 8 }
 9 
10 stringt::~stringt()
11 {
12 
13 }
14 
15 QString stringt::Ttext() const
16 {
17     return m_String;
18 }
19 
20 void stringt::setTtext(const QString str)
21 {
22     m_String = str;
23 }

接着就是main文件里面,注册这个类就可以了,用qmlRegisterType这个函数

 1 #include <QApplication>
 2 #include <QQmlApplicationEngine>
 3 #include <QtQml>
 4 #include "stringt.h"
 5 
 6 int main(int argc, char *argv[])
 7 {
 8     QApplication app(argc, argv);
 9 
10     qmlRegisterType<stringt>("m.stringT", 1, 0, "StringT");
11                    //要导入的类  包名 主版本号 次版本号 元素名
12     QQmlApplicationEngine engine;
13     engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
14 
15     return app.exec();
16 }

最后就是QML文件了。这里定义了两个矩形。点击左边的矩形后,右边的矩形会改变颜色和文本。

 1 import QtQuick 2.4
 2 import QtQuick.Controls 1.3
 3 import QtQuick.Window 2.2
 4 import QtQuick.Dialogs 1.2
 5 import m.stringT 1.0    //导入类
 6 
 7 ApplicationWindow {
 8     title: qsTr("Hello World")
 9     width: 640
10     height: 480
11     visible: true
12 
13     StringT{    //创建一个元素
14         id: stringT
15     }
16 
17     Rectangle {
18         id: rect1
19         x: 12; y: 12
20         width: 60; height: 60
21         color: "lightsteelblue"
22         MouseArea {
23             id: rect1_area
24             anchors.fill: parent
25             onClicked:
26             {
27                 rect2.color = "lightgreen"
28                 rect2_text.text = stringT.Ttext
29             }
30         }
31     }
32 
33     Rectangle {
34         id: rect2
35         x: rect1.x + rect1.width + 10
36         y: rect1.y
37         width: rect1.width; height: rect1.height
38         border.color: "lightsteelblue"
39         border.width: 3
40         radius: 3
41         Text {
42             id: rect2_text
43             text: qsTr("Hello")
44             font.pixelSize: 12
45             anchors.centerIn: parent
46         }
47     }
48 }

效果大概是这样的。

 

 ---------------------------------传值给C++类---------------------------------

      上面,我们将C++注册到QML,便使QML可以访问C++的内容。那怎样将QML中的值,比如Text传给C++呢。只要在函数开头使用Q_INVOKABLE宏便可以了。比如上面的类中的set方法。

1 //void setTtext(const QString str);
2 Q_INVOKABLE void setTtext(const QString str);

然后在main.qml中就可以使用这个set方法了

 1     Rectangle {
 2         id: rect1
 3         x: 12; y: 12
 4         width: 60; height: 60
 5         color: "lightsteelblue"
 6         Text {
 7             id: rect1_text
 8             text: qsTr("QML")
 9             anchors.centerIn: parent
10         }
11         MouseArea {
12             id: rect1_area
13             anchors.fill: parent
14             onClicked:
15             {
16                 rect2.color = "lightgreen"
17                 stringT.setTtext(rect1_text.text)
18                 rect2_text.text = stringT.Ttext
19             }
20         }
21     }

这段代码里面给第一个矩形里面设置了Text。然后在点击这个矩形的时候,第二个矩形的Text就会变成和第一个Text一样了。QML先是调用了类的write方法m_String,接着调用了Ttext这个read方法

posted @ 2014-12-24 15:11  hanfengcan  阅读(2725)  评论(0编辑  收藏  举报