博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
QT之在QML中使用C++类和对象的两种方式
阅读量:4303 次
发布时间:2019-05-27

本文共 12264 字,大约阅读时间需要 40 分钟。

  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 
#include
class ColorMaker : public QObject{ Q_OBJECT Q_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 
#include
#include
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
int qmlRegisterType(const char *uri, int versionMajor, int versionMinor, const char *qmlName); template
int qmlRegisterType(const char *uri, int versionMajor, int versionMinor, const char *qmlName);

  uri 指定唯一的包名

  qmlname 是QML中可以使用的类名

qmlRegisterType
("an.qt.ColorMaker", 1, 0, "ColorMaker");

3. 在QML中导入类型

  一旦你在C++中注册好了QML类型,就可以在QML文档中引入你注册的包,然后使用注册的类型了

import an.qt.ColorMaker 1.0

复制代码

#include 
#include
#include
#include
#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
("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.2import QtQuick.Window 2.2import QtQuick.Controls 1.4import QtQuick.Controls.Styles 1.4import QtQuick.Dialogs 1.3import QtQml 2.11import 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:quit        text:"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: 600    height: 600    Image {        id: imageLabel;        width: 600;        height: 540;        anchors.top: parent.top        anchors.left: parent.left        fillMode: Image.PreserveAspectFit        source: "http://images.cnblogs.com/cnblogs_com/xiaobingqianrui/1185116/o_Image%201.png"    }    Button    {        id:openBtn        width: 100;        height: 40;        text: "Open";        anchors.top:imageLabel.bottom        anchors.topMargin: 10;        anchors.left: parent.left        anchors.leftMargin: 10;        onClicked:fileDialog.open();    }    Label    {        id:pathLabel;        text: "Hello world"        font.pixelSize: 22        font.italic: true        color: "steelblue"        anchors.top:imageLabel.bottom        anchors.topMargin: 10;        anchors.left: openBtn.right        anchors.leftMargin: 10    }    FileDialog    {        id:fileDialog        title: "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.2import QtQuick.Window 2.2import QtQuick.Controls 1.4import QtQuick.Controls.Styles 1.4import QtQuick.Dialogs 1.3import 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:quit        text:"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;        }    }}

复制代码

转载地址:http://qdlws.baihongyu.com/

你可能感兴趣的文章
vue+springboot分页交互
查看>>
vue+springboot打包发布
查看>>
vibe目标检测python代码
查看>>
Flink-环境搭建
查看>>
Redis-与spring的集成(XML形式)
查看>>
Spring-读取Classpath下的文件资源
查看>>
Mysql-存储过程
查看>>
SpringMvc-允许访问静态资源
查看>>
Spring-BeanPostProcessor/InitalizingBean
查看>>
Excel操作-ApachePOI
查看>>
Eclipse-复制项目
查看>>
解析XML格式的数据-XStream
查看>>
SpringBoot-Websocket
查看>>
Spring-core-SpringFactoriesLoader类
查看>>
SpringMvc-HttpSession/HttpServletRequest
查看>>
Eclipse-无法引用maven依赖的类/没有MavenDependencies/没有buildpath
查看>>
Redis-与SpringBoot的集成
查看>>
Netty-5-客户端的创建并且接受服务端的数据
查看>>
SpringMvc-HandlerExceptionResolver
查看>>
Eclipse-properties文件乱码问题
查看>>