QT之在QML中使用C++类和对象的两种方式
- 一 類的方式實現在QML中使用C++對象
- 二 對象的方式實現在QML中使用C++對象
QML其實是對ECMAScript的擴展,融合了Qt object系統,它是一種新的解釋性語言,QML引擎雖然由Qt C++實現,但QML對象的運行環境說到底和C++對象的上下文環境是不通的,是平行的兩個世界,如果想在QML中訪問C++對象,那么必然要找到一種途徑在兩個運行環境之間建立溝通的橋梁。
Qt提供了兩種在QML環境中使用C++對象的方式:
(1)在C++中實現一個類,注冊為QML環境的一個類型,在QML環境中使用該類型創建對象
(2)在C++中構造一個對象,將這個對象設置為QML的上下文屬性,在QML環境中直接使用該屬性
回到頂部
一 類的方式實現在QML中使用C++對象
1. 定義可以導出的C++類
要想將一個類或對象導出到QML中,必須滿足以下幾個條件:
(1)從QObject或QObject的派生類繼承
(2)使用Q_OBJECT宏
(3)Q_INVOKABLE宏
在定義一個類的成員函數時使用Q_INVOKABLE宏來修飾,就可以讓該方法被元對象系統調用,這個宏必須放在返回類型前面
(4)Q_ENUMS宏
如果要導出的類定義了想在QML中使用的枚舉類型,可以使用Q_ENUM宏將該枚舉注冊到元對象系統中
(5)Q_PROPERTY宏
Q_PROPERTY宏用來定義可以通過元對象系統訪問的屬性,通過它定義的屬性,可以在QML中訪問,修改,也可以在屬性變化時發射特定的信號
? 例子:
#ifndef COLORMAKER_H #define COLORMAKER_H#include <QObject> #include <QColor> class ColorMaker : public QObject {Q_OBJECTQ_ENUMS(GenerateAlgorithm)Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged)Q_PROPERTY(QColor timeColor READ timeColor) public:explicit ColorMaker(QObject *parent = nullptr);~ColorMaker();enum GenerateAlgorithm{RandomRGB,RandomRed,RandomGreen,RandomBlue,LinearIcrease};QColor color() const {return m_currentColor;}void setColor(const QColor& color);QColor timeColor() const;Q_INVOKABLE GenerateAlgorithm alorithm() const;Q_INVOKABLE void serAlgorithm(GenerateAlgorithm algorithm);signals:void colorChanged(const QColor& color);void currentTime(const QString& strTime);public slots:void start();void stop();protected:void timerEvent(QTimerEvent *e);private:GenerateAlgorithm m_algorithm;QColor m_currentColor;int m_nColorTimer; };#endif // COLORMAKER_H #include "colormaker.h" #include <QTime> #include <QTimerEvent> #include <QDebug>ColorMaker::ColorMaker(QObject *parent): QObject(parent),m_algorithm(RandomRGB),m_currentColor(Qt::black),m_nColorTimer(0) {qsrand(QDateTime::currentDateTime().toTime_t()); }ColorMaker::~ColorMaker() {}void ColorMaker::setColor(const QColor &color) {m_currentColor = color;emit colorChanged(color); }QColor ColorMaker::timeColor() const {QTime time = QTime::currentTime();qDebug() << time.toString("yyyy-MM-dd hh:mm:ss");int r = time.hour();int g = time.minute() * 2;int b = time.second() * 4;qDebug() << r << ":"<< g << ":"<< b;return QColor(r,g,b); }ColorMaker::GenerateAlgorithm ColorMaker::alorithm() const {return m_algorithm; }void ColorMaker::serAlgorithm(ColorMaker::GenerateAlgorithm algorithm) {m_algorithm = algorithm; }void ColorMaker::start() {qDebug() << "ColorMaker start";if (m_nColorTimer == 0){m_nColorTimer = startTimer(1000);} }void ColorMaker::stop() {if (m_nColorTimer > 0){killTimer(m_nColorTimer);m_nColorTimer = 0;} }void ColorMaker::timerEvent(QTimerEvent *e) {if (e->timerId() == m_nColorTimer){switch (m_algorithm) {case RandomRGB:m_currentColor.setRgb(qrand()%255, qrand()%255,qrand()%255);break;case RandomRed:m_currentColor.setRed(qrand()%255);break;case RandomGreen:m_currentColor.setGreen(qrand()%255);break;case RandomBlue:m_currentColor.setBlue(qrand()%255);break;case LinearIcrease:{int r = m_currentColor.red() + 10;int g = m_currentColor.green() + 10;int b = m_currentColor.blue() + 10;m_currentColor.setRgb(r%255,g%255,b%255);}break;default:break;}emit colorChanged(m_currentColor);emit currentTime(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"));}else{return QObject::timerEvent(e);} }2. 注冊QML類型
要注冊一個QML類型,有多種方法:
qmlRegisterSingletonType()注冊一個單例類型
qmlRegisterType()注冊一個非單例類型
qmlRegisterTypeNotAvaliable()注冊一個類型用來占位
qmlRegisterUncreatableType()通常用來注冊一個具有附加屬性的附加類型,具體參考Qt SDK
template<typename T>int qmlRegisterType(const char *uri, int versionMajor, int versionMinor, const char *qmlName);template<typename T, int metaObjectRevision>int qmlRegisterType(const char *uri, int versionMajor, int versionMinor, const char *qmlName);uri 指定唯一的包名
qmlname 是QML中可以使用的類名
qmlRegisterType<ColorMaker>("an.qt.ColorMaker", 1, 0, "ColorMaker");3. 在QML中導入類型
一旦你在C++中注冊好了QML類型,就可以在QML文檔中引入你注冊的包,然后使用注冊的類型了
import an.qt.ColorMaker 1.0 #include <QGuiApplication> #include <QQmlApplicationEngine> #include <QQuickView> #include <QtQml> #include "colormaker.h"int main(int argc, char *argv[]) {QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);QGuiApplication app(argc, argv);//QQmlApplicationEngine engine;//engine.load(QUrl(QStringLiteral("qrc:/main.qml")));//if (engine.rootObjects().isEmpty())// return -1;qmlRegisterType<ColorMaker>("an.qt.ColorMaker", 1, 0, "ColorMaker");QQuickView viewer;viewer.setResizeMode(QQuickView::SizeRootObjectToView);viewer.setSource(QUrl("qrc:///main.qml"));viewer.show();return app.exec(); }4. 在QML中創建由C++導出的類型的實例并使用
引入包后,你可以在QML中創建 C++導入類型的對象了,與QML內建類型的使用完全一樣。
Rectangle {width: 360;height: 360;ColorMaker{id:colorMaker;color:Qt.green;} }例:
import QtQuick 2.2 import QtQuick.Window 2.2 import QtQuick.Controls 1.4 import QtQuick.Controls.Styles 1.4 import QtQuick.Dialogs 1.3 import QtQml 2.11 import an.qt.ColorMaker 1.0Rectangle {width: 360;height: 360;Text {id: timeLabel;anchors.left: parent.left;anchors.leftMargin: 4;anchors.top : parent.top;anchors.topMargin: 4;font.pixelSize: 26;}ColorMaker{id:colorMaker;color:Qt.green;}Rectangle{id:colorRect;anchors.centerIn: parent;width: 200;height: 200;color: "blue";}Button{id:start;text:"start";anchors.left: parent.left;anchors.leftMargin: 4;anchors.bottom: parent.bottom;anchors.bottomMargin: 4;onClicked:{console.log("start onClicked");colorMaker.start();}}Button{id:stop;text:"stop";anchors.left: start.right;anchors.leftMargin: 4;anchors.bottom: start.bottom;anchors.bottomMargin: 4;onClicked:{colorMaker.stop();}}function changeAlgorithm(button, algorithm){switch(algorithm){case 0:button.text = "RandomRGB"break;case 1:button.text ="RandomRed";break;case 2:button.text ="RandomGreen";break;case 3:button.text ="RandomBlue";break;case 4:button.text ="LinearIncrease";break;}}Button{id:colorAlgorithm;text:"RandomRGB";anchors.left:stop.right;anchors.leftMargin: 4;anchors.bottom: stop.bottom;onClicked:{var algorithm = (colorMaker.alorithm() + 1 ) % 5;changeAlgorithm(colorAlgorithm,algorithm);colorMaker.serAlgorithm(algorithm);}}Button{id:quittext:"quit"anchors.left: colorAlgorithm.right;anchors.leftMargin: 4;anchors.bottom: colorAlgorithm.bottom;onClicked:{Qt.quit();}}Component.onCompleted:{colorMaker.color = Qt.rgba(0,180,120,255);colorMaker.serAlgorithm(colorMaker.LinearIcrease);changeAlgorithm(colorAlgorithm,colorMaker.alorithm());}Connections{target: colorMaker;onCurrentTime:{timeLabel.text = strTime;console.log("onCurrentTime");// timeLabel.color = colorMaker.timeColor;}}Connections{target: colorMaker;onColorChanged:{colorRect.color = color;}} }/*Rectangle {width: 600height: 600Image {id: imageLabel;width: 600;height: 540;anchors.top: parent.topanchors.left: parent.leftfillMode: Image.PreserveAspectFitsource: "http://images.cnblogs.com/cnblogs_com/xiaobingqianrui/1185116/o_Image%201.png"}Button{id:openBtnwidth: 100;height: 40;text: "Open";anchors.top:imageLabel.bottomanchors.topMargin: 10;anchors.left: parent.leftanchors.leftMargin: 10;onClicked:fileDialog.open();}Label{id:pathLabel;text: "Hello world"font.pixelSize: 22font.italic: truecolor: "steelblue"anchors.top:imageLabel.bottomanchors.topMargin: 10;anchors.left: openBtn.rightanchors.leftMargin: 10}FileDialog{id:fileDialogtitle: "please choose a file"nameFilters: ["Image Files (*.jpg *.png *.gif)"]onAccepted:{imageLabel.source=fileDialog.fileUrl;console.log(fileDialog.fileUrl);var imageFile = new String(fileDialog.fileUrl);pathLabel.text=imageFile.slice(8);}} }*/回到頂部
二 對象的方式實現在QML中使用C++對象
1. 注冊屬性
viewer.rootContext()->setContextProperty("colorMaker", new ColorMaker);2. 在QML中使用關聯到的C++對象的屬性
一旦調用setContextProperty()導出了屬性,就可以在QML中使用了,不需要import語句
import QtQuick 2.2 import QtQuick.Window 2.2 import QtQuick.Controls 1.4 import QtQuick.Controls.Styles 1.4 import QtQuick.Dialogs 1.3 import QtQml 2.11 //import an.qt.ColorMaker 1.0Rectangle {width: 360;height: 360;Text {id: timeLabel;anchors.left: parent.left;anchors.leftMargin: 4;anchors.top : parent.top;anchors.topMargin: 4;font.pixelSize: 26;}/* ColorMaker{id:colorMaker;color:Qt.green;}*/Rectangle{id:colorRect;anchors.centerIn: parent;width: 200;height: 200;color: "blue";}Button{id:start;text:"start";anchors.left: parent.left;anchors.leftMargin: 4;anchors.bottom: parent.bottom;anchors.bottomMargin: 4;onClicked:{console.log("start onClicked");colorMaker.start();}}Button{id:stop;text:"stop";anchors.left: start.right;anchors.leftMargin: 4;anchors.bottom: start.bottom;anchors.bottomMargin: 4;onClicked:{colorMaker.stop();}}function changeAlgorithm(button, algorithm){switch(algorithm){case 0:button.text = "RandomRGB"break;case 1:button.text ="RandomRed";break;case 2:button.text ="RandomGreen";break;case 3:button.text ="RandomBlue";break;case 4:button.text ="LinearIncrease";break;}}Button{id:colorAlgorithm;text:"RandomRGB";anchors.left:stop.right;anchors.leftMargin: 4;anchors.bottom: stop.bottom;onClicked:{var algorithm = (colorMaker.alorithm() + 1 ) % 5;changeAlgorithm(colorAlgorithm,algorithm);colorMaker.serAlgorithm(algorithm);}}Button{id:quittext:"quit"anchors.left: colorAlgorithm.right;anchors.leftMargin: 4;anchors.bottom: colorAlgorithm.bottom;onClicked:{Qt.quit();}}Component.onCompleted:{colorMaker.color = Qt.rgba(0,180,120,255);//colorMaker.serAlgorithm(colorMaker.LinearIcrease);colorMaker.serAlgorithm(2);changeAlgorithm(colorAlgorithm,colorMaker.alorithm());}Connections{target: colorMaker;onCurrentTime:{timeLabel.text = strTime;console.log("onCurrentTime");// timeLabel.color = colorMaker.timeColor;}}Connections{target: colorMaker;onColorChanged:{colorRect.color = color;}} }總結
以上是生活随笔為你收集整理的QT之在QML中使用C++类和对象的两种方式的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 解决: Intellij IDEA 运行
- 下一篇: Docker 方式安装 RabbitMQ