欢迎访问 生活随笔!

生活随笔

当前位置: 首页 > 编程语言 > c/c++ >内容正文

c/c++

QT之在QML中使用C++类和对象的两种方式

发布时间:2023/12/18 c/c++ 35 豆豆
生活随笔 收集整理的这篇文章主要介绍了 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++类和对象的两种方式的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。