• 一 类的方式实现在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++类和对象的两种方式相关推荐

  1. Android中实现SQLite数据库CRUD操作的两种方式

    Android中实现SQLite数据库CRUD操作的两种方式 SQLite是一款轻量级的关系型数据库,具有运行速度.占用资源少的特点.通常只需要几百KB的内存就够了,因此特别适合在移动设备上使用.SQ ...

  2. java 给对象创建实例_Java中创建(实例化)对象的五种方式

    Java中创建(实例化)对象的五种方式1.用new语句创建对象,这是最常见的创建对象的方法. 2.通过工厂方法返回对象,如:String str = String.valueOf(23); 3.运用反 ...

  3. Java中创建(实例化)对象的五种方式

    Java中创建(实例化)对象的五种方式 1.用new语句创建对象,这是最常见的创建对象的方法. 2.通过工厂方法返回对象,如:String str = String.valueOf(23);  3.运 ...

  4. android布局密码,Android中EditText显示明文与密码的两种方式

    效果图如下所述: 布局 xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="h ...

  5. idea中java程序打jar包的两种方式(超详细)

    java程序打成的jar包有两种类型,一种是可直接执行的runnable jar文件,另一种是包含多个主类,运行时需要指定主类全类名的jar包,下面我们细说在idea中两种jar包的打包方法及执行ja ...

  6. Android中界面实现全屏显示的两种方式

    在开发android的应用当中,我们会遇到将一些界面设置为全屏显示的格式,有两种实现的方法.其一是在Java代码中实现,其二是在配置文件中实现. 1. 在Java代码中设置 super.onCreat ...

  7. java中产生对象的两种方式

    /** 普通new对象的过程!*/Person pp = new Person();System.out.println(pp);/** 利用代用参数的构造器产生对象实例!* 首先获得相应带参数的构造 ...

  8. linux下scp提示文件名过长,Linux中crontab下scp文件传输的两种方式

    Linux下文件传输一般有两个命令scp.ftp(工具需要下载安装) 本文主要讲讲scp的文件传输脚本 1.scp ssh-keygen -t rsa免输入密码,传输 这里假设主机A 用来获到主机B的 ...

  9. redis中存储java对象的两种方式

    根据redis的存储原理,Redis的key和value都支持二进制安全的字符串 1.利用序列化和反序列化的方式 存储java对象我们可以通过对象的序列化与反序列化完成存储于取出,这样就可以使用red ...

最新文章

  1. 欠阿里云一分钱,会是什么样的后果...
  2. SAP PM 初级系列18 - 为维修工单分配Permit
  3. Spring Security OAuth 2开发者指南译
  4. logback:用slf4j+logback实现多功能日志解决方案
  5. 高中计算机应用基础试讲,试讲计算机应用基础.ppt
  6. 单位阶跃信号是周期信号吗_手机信号变成“HD”,是代表没有信号吗?你的手机正在被扣费...
  7. ABP VNext实践之搭建可用于生产的IdentityServer4
  8. word 7桌面上的计算机图标是,怎么设置win7系统桌面图标都变成word图标的处理办法...
  9. 云计算的概念_云计算概念掀起涨停潮 美利云奠定板块龙头地位
  10. 深圳惊现“马云网络有限公司” 网友:你好 我是马云公司CEO
  11. 今天加入了“宇宙通史:木星”
  12. 华为鸿蒙系统面对困难,华为鸿蒙面临的2个新困难
  13. java并发线程池---了解ThreadPoolExecutor就够了
  14. ActiveMQ官方文档翻译-内嵌消息中间件
  15. 计算机桌面声音图标,声音图标不见了,教您电脑声音图标不见了如何解决
  16. Airdrop式社交:富友,你的airdrop没关
  17. 十大宽带共享组建网络方式推荐
  18. 图解2018双十一背后的阿里云技术
  19. 一周肝出Linux之远程服务详解(ssh远程登录、scp远程复制、sftp安全下载、TCP Wrappers访问控制)
  20. 人类群星闪耀时——决定人类历史的10个瞬间

热门文章

  1. 并行程序设计(MPICH环境配置)win10
  2. qt单步调试linux程序,用Qt 调用GDB调试 Arm程序 详细步骤----可单步执行每一行
  3. linux苹果开发者p12,苹果testflight发布流程
  4. 开发提交审核流程_小程序如何提交审核,多久能通过?
  5. mx250 计算能力_熟悉的刀法:英伟达 MX 250 也有 25W 和 10W 两个版本
  6. 微型计算机物理地址转换,微型计算机及接口技术2015年4月真题试题(04732)
  7. c语言subscripted_c语言。数组的问题。急!
  8. 中年危机来了?35岁是分水岭?
  9. 循环训练_要想循环增肌,且不会伤害身体,你可以这样安排力量训练
  10. 怎么写字_写字楼外卖员不让进怎么办?写字楼外卖柜提供解决方案!