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++类和对象的两种方式相关推荐
- Android中实现SQLite数据库CRUD操作的两种方式
Android中实现SQLite数据库CRUD操作的两种方式 SQLite是一款轻量级的关系型数据库,具有运行速度.占用资源少的特点.通常只需要几百KB的内存就够了,因此特别适合在移动设备上使用.SQ ...
- java 给对象创建实例_Java中创建(实例化)对象的五种方式
Java中创建(实例化)对象的五种方式1.用new语句创建对象,这是最常见的创建对象的方法. 2.通过工厂方法返回对象,如:String str = String.valueOf(23); 3.运用反 ...
- Java中创建(实例化)对象的五种方式
Java中创建(实例化)对象的五种方式 1.用new语句创建对象,这是最常见的创建对象的方法. 2.通过工厂方法返回对象,如:String str = String.valueOf(23); 3.运 ...
- android布局密码,Android中EditText显示明文与密码的两种方式
效果图如下所述: 布局 xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="h ...
- idea中java程序打jar包的两种方式(超详细)
java程序打成的jar包有两种类型,一种是可直接执行的runnable jar文件,另一种是包含多个主类,运行时需要指定主类全类名的jar包,下面我们细说在idea中两种jar包的打包方法及执行ja ...
- Android中界面实现全屏显示的两种方式
在开发android的应用当中,我们会遇到将一些界面设置为全屏显示的格式,有两种实现的方法.其一是在Java代码中实现,其二是在配置文件中实现. 1. 在Java代码中设置 super.onCreat ...
- java中产生对象的两种方式
/** 普通new对象的过程!*/Person pp = new Person();System.out.println(pp);/** 利用代用参数的构造器产生对象实例!* 首先获得相应带参数的构造 ...
- linux下scp提示文件名过长,Linux中crontab下scp文件传输的两种方式
Linux下文件传输一般有两个命令scp.ftp(工具需要下载安装) 本文主要讲讲scp的文件传输脚本 1.scp ssh-keygen -t rsa免输入密码,传输 这里假设主机A 用来获到主机B的 ...
- redis中存储java对象的两种方式
根据redis的存储原理,Redis的key和value都支持二进制安全的字符串 1.利用序列化和反序列化的方式 存储java对象我们可以通过对象的序列化与反序列化完成存储于取出,这样就可以使用red ...
最新文章
- 欠阿里云一分钱,会是什么样的后果...
- SAP PM 初级系列18 - 为维修工单分配Permit
- Spring Security OAuth 2开发者指南译
- logback:用slf4j+logback实现多功能日志解决方案
- 高中计算机应用基础试讲,试讲计算机应用基础.ppt
- 单位阶跃信号是周期信号吗_手机信号变成“HD”,是代表没有信号吗?你的手机正在被扣费...
- ABP VNext实践之搭建可用于生产的IdentityServer4
- word 7桌面上的计算机图标是,怎么设置win7系统桌面图标都变成word图标的处理办法...
- 云计算的概念_云计算概念掀起涨停潮 美利云奠定板块龙头地位
- 深圳惊现“马云网络有限公司” 网友:你好 我是马云公司CEO
- 今天加入了“宇宙通史:木星”
- 华为鸿蒙系统面对困难,华为鸿蒙面临的2个新困难
- java并发线程池---了解ThreadPoolExecutor就够了
- ActiveMQ官方文档翻译-内嵌消息中间件
- 计算机桌面声音图标,声音图标不见了,教您电脑声音图标不见了如何解决
- Airdrop式社交:富友,你的airdrop没关
- 十大宽带共享组建网络方式推荐
- 图解2018双十一背后的阿里云技术
- 一周肝出Linux之远程服务详解(ssh远程登录、scp远程复制、sftp安全下载、TCP Wrappers访问控制)
- 人类群星闪耀时——决定人类历史的10个瞬间
热门文章
- 并行程序设计(MPICH环境配置)win10
- qt单步调试linux程序,用Qt 调用GDB调试 Arm程序 详细步骤----可单步执行每一行
- linux苹果开发者p12,苹果testflight发布流程
- 开发提交审核流程_小程序如何提交审核,多久能通过?
- mx250 计算能力_熟悉的刀法:英伟达 MX 250 也有 25W 和 10W 两个版本
- 微型计算机物理地址转换,微型计算机及接口技术2015年4月真题试题(04732)
- c语言subscripted_c语言。数组的问题。急!
- 中年危机来了?35岁是分水岭?
- 循环训练_要想循环增肌,且不会伤害身体,你可以这样安排力量训练
- 怎么写字_写字楼外卖员不让进怎么办?写字楼外卖柜提供解决方案!