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 运行
- 下一篇: QT中使用OpenGL绘制图形