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中访问,修改,也可以在属性变化时发射特定的信号

例子:

  1. #ifndef COLORMAKER_H
  2. #define COLORMAKER_H
  3.  
  4. #include <QObject>
  5. #include <QColor>
  6. class ColorMaker : public QObject
  7. {
  8. Q_OBJECT
  9. Q_ENUMS(GenerateAlgorithm)
  10. Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged)
  11. Q_PROPERTY(QColor timeColor READ timeColor)
  12. public:
  13. explicit ColorMaker(QObject *parent = nullptr);
  14. ~ColorMaker();
  15.  
  16. enum GenerateAlgorithm
  17. {
  18. RandomRGB,
  19. RandomRed,
  20. RandomGreen,
  21. RandomBlue,
  22. LinearIcrease
  23. };
  24.  
  25. QColor color() const {return m_currentColor;}
  26. void setColor(const QColor& color);
  27. QColor timeColor() const;
  28.  
  29. Q_INVOKABLE GenerateAlgorithm alorithm() const;
  30. Q_INVOKABLE void serAlgorithm(GenerateAlgorithm algorithm);
  31.  
  32. signals:
  33. void colorChanged(const QColor& color);
  34. void currentTime(const QString& strTime);
  35.  
  36. public slots:
  37. void start();
  38. void stop();
  39.  
  40. protected:
  41. void timerEvent(QTimerEvent *e);
  42.  
  43. private:
  44. GenerateAlgorithm m_algorithm;
  45. QColor m_currentColor;
  46. int m_nColorTimer;
  47. };
  48.  
  49. #endif // COLORMAKER_H

colormaker.h

  1. #include "colormaker.h"
  2. #include <QTime>
  3. #include <QTimerEvent>
  4. #include <QDebug>
  5.  
  6. ColorMaker::ColorMaker(QObject *parent)
  7. : QObject(parent)
  8. ,m_algorithm(RandomRGB)
  9. ,m_currentColor(Qt::black)
  10. ,m_nColorTimer()
  11. {
  12. qsrand(QDateTime::currentDateTime().toTime_t());
  13. }
  14.  
  15. ColorMaker::~ColorMaker()
  16. {
  17.  
  18. }
  19.  
  20. void ColorMaker::setColor(const QColor &color)
  21. {
  22. m_currentColor = color;
  23. emit colorChanged(color);
  24. }
  25.  
  26. QColor ColorMaker::timeColor() const
  27. {
  28. QTime time = QTime::currentTime();
  29. qDebug() << time.toString("yyyy-MM-dd hh:mm:ss");
  30. int r = time.hour();
  31. int g = time.minute() * ;
  32. int b = time.second() * ;
  33. qDebug() << r << ":"<< g << ":"<< b;
  34. return QColor(r,g,b);
  35. }
  36.  
  37. ColorMaker::GenerateAlgorithm ColorMaker::alorithm() const
  38. {
  39. return m_algorithm;
  40. }
  41.  
  42. void ColorMaker::serAlgorithm(ColorMaker::GenerateAlgorithm algorithm)
  43. {
  44. m_algorithm = algorithm;
  45. }
  46.  
  47. void ColorMaker::start()
  48. {
  49. qDebug() << "ColorMaker start";
  50. if (m_nColorTimer == )
  51. {
  52. m_nColorTimer = startTimer();
  53. }
  54. }
  55.  
  56. void ColorMaker::stop()
  57. {
  58. if (m_nColorTimer > )
  59. {
  60. killTimer(m_nColorTimer);
  61. m_nColorTimer = ;
  62. }
  63. }
  64.  
  65. void ColorMaker::timerEvent(QTimerEvent *e)
  66. {
  67. if (e->timerId() == m_nColorTimer)
  68. {
  69. switch (m_algorithm) {
  70. case RandomRGB:
  71. m_currentColor.setRgb(qrand()%, qrand()%,qrand()%);
  72. break;
  73. case RandomRed:
  74. m_currentColor.setRed(qrand()%);
  75. break;
  76. case RandomGreen:
  77. m_currentColor.setGreen(qrand()%);
  78. break;
  79. case RandomBlue:
  80. m_currentColor.setBlue(qrand()%);
  81. break;
  82. case LinearIcrease:
  83. {
  84. int r = m_currentColor.red() + ;
  85. int g = m_currentColor.green() + ;
  86. int b = m_currentColor.blue() + ;
  87. m_currentColor.setRgb(r%,g%,b%);
  88. }
  89. break;
  90. default:
  91. break;
  92. }
  93. emit colorChanged(m_currentColor);
  94. emit currentTime(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"));
  95. }
  96. else
  97. {
  98. return QObject::timerEvent(e);
  99. }
  100. }

colormaker.cpp

2. 注册QML类型

  要注册一个QML类型,有多种方法:

  qmlRegisterSingletonType()注册一个单例类型

  qmlRegisterType()注册一个非单例类型

  qmlRegisterTypeNotAvaliable()注册一个类型用来占位

  qmlRegisterUncreatableType()通常用来注册一个具有附加属性的附加类型,具体参考Qt SDK

  1.  template<typename T>
  2. int qmlRegisterType(const char *uri, int versionMajor, int versionMinor, const char *qmlName);
  3.  
  4. template<typename T, int metaObjectRevision>
  5. int qmlRegisterType(const char *uri, int versionMajor, int versionMinor, const char *qmlName);

  uri 指定唯一的包名

  qmlname 是QML中可以使用的类名

  1. qmlRegisterType<ColorMaker>("an.qt.ColorMaker", , , "ColorMaker");

3. 在QML中导入类型

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

  1. import an.qt.ColorMaker 1.0
  1. #include <QGuiApplication>
  2. #include <QQmlApplicationEngine>
  3. #include <QQuickView>
  4. #include <QtQml>
  5. #include "colormaker.h"
  6.  
  7. int main(int argc, char *argv[])
  8. {
  9. QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
  10.  
  11. QGuiApplication app(argc, argv);
  12.  
  13. //QQmlApplicationEngine engine;
  14. //engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
  15. //if (engine.rootObjects().isEmpty())
  16. // return -1;
  17.  
  18. qmlRegisterType<ColorMaker>("an.qt.ColorMaker", , , "ColorMaker");
  19. QQuickView viewer;
  20. viewer.setResizeMode(QQuickView::SizeRootObjectToView);
  21. viewer.setSource(QUrl("qrc:///main.qml"));
  22. viewer.show();
  23.  
  24. return app.exec();
  25. }

4. 在QML中创建由C++导出的类型的实例并使用  

  引入包后,你可以在QML中创建 C++导入类型的对象了,与QML内建类型的使用完全一样。

  1. Rectangle
  2. {
  3. width: ;
  4. height: ;
  5.  
  6. ColorMaker
  7. {
  8. id:colorMaker;
  9. color:Qt.green;
  10. }
  11. }

  例:

  1. import QtQuick 2.2
  2. import QtQuick.Window 2.2
  3. import QtQuick.Controls 1.4
  4. import QtQuick.Controls.Styles 1.4
  5. import QtQuick.Dialogs 1.3
  6. import QtQml 2.11
  7. import an.qt.ColorMaker 1.0
  8.  
  9. Rectangle
  10. {
  11. width: ;
  12. height: ;
  13. Text {
  14. id: timeLabel;
  15. anchors.left: parent.left;
  16. anchors.leftMargin: ;
  17. anchors.top : parent.top;
  18. anchors.topMargin: ;
  19. font.pixelSize: ;
  20. }
  21.  
  22. ColorMaker
  23. {
  24. id:colorMaker;
  25. color:Qt.green;
  26. }
  27.  
  28. Rectangle
  29. {
  30. id:colorRect;
  31. anchors.centerIn: parent;
  32. width: ;
  33. height: ;
  34. color: "blue";
  35. }
  36.  
  37. Button
  38. {
  39. id:start;
  40. text:"start";
  41. anchors.left: parent.left;
  42. anchors.leftMargin: ;
  43. anchors.bottom: parent.bottom;
  44. anchors.bottomMargin: ;
  45. onClicked:
  46. {
  47. console.log("start onClicked");
  48. colorMaker.start();
  49. }
  50. }
  51.  
  52. Button
  53. {
  54. id:stop;
  55. text:"stop";
  56. anchors.left: start.right;
  57. anchors.leftMargin: ;
  58. anchors.bottom: start.bottom;
  59. anchors.bottomMargin: ;
  60. onClicked:
  61. {
  62. colorMaker.stop();
  63. }
  64. }
  65.  
  66. function changeAlgorithm(button, algorithm)
  67. {
  68. switch(algorithm)
  69. {
  70. case :
  71. button.text = "RandomRGB"
  72. break;
  73. case :
  74. button.text ="RandomRed";
  75. break;
  76. case :
  77. button.text ="RandomGreen";
  78. break;
  79. case :
  80. button.text ="RandomBlue";
  81. break;
  82. case :
  83. button.text ="LinearIncrease";
  84. break;
  85. }
  86. }
  87.  
  88. Button
  89. {
  90. id:colorAlgorithm;
  91. text:"RandomRGB";
  92. anchors.left:stop.right;
  93. anchors.leftMargin: ;
  94. anchors.bottom: stop.bottom;
  95. onClicked:
  96. {
  97. var algorithm = (colorMaker.alorithm() + ) % ;
  98. changeAlgorithm(colorAlgorithm,algorithm);
  99. colorMaker.serAlgorithm(algorithm);
  100. }
  101. }
  102. Button
  103. {
  104. id:quit
  105. text:"quit"
  106. anchors.left: colorAlgorithm.right;
  107. anchors.leftMargin: ;
  108. anchors.bottom: colorAlgorithm.bottom;
  109. onClicked:
  110. {
  111. Qt.quit();
  112. }
  113. }
  114.  
  115. Component.onCompleted:
  116. {
  117. colorMaker.color = Qt.rgba(,,,);
  118. colorMaker.serAlgorithm(colorMaker.LinearIcrease);
  119. changeAlgorithm(colorAlgorithm,colorMaker.alorithm());
  120. }
  121.  
  122. Connections
  123. {
  124. target: colorMaker;
  125.  
  126. onCurrentTime:
  127. {
  128. timeLabel.text = strTime;
  129. console.log("onCurrentTime");
  130. // timeLabel.color = colorMaker.timeColor;
  131. }
  132. }
  133.  
  134. Connections
  135. {
  136. target: colorMaker;
  137. onColorChanged:
  138. {
  139. colorRect.color = color;
  140. }
  141. }
  142. }
  143.  
  144. /*Rectangle
  145. {
  146. width: 600
  147. height: 600
  148.  
  149. Image {
  150. id: imageLabel;
  151. width: 600;
  152. height: 540;
  153. anchors.top: parent.top
  154. anchors.left: parent.left
  155. fillMode: Image.PreserveAspectFit
  156. source: "http://images.cnblogs.com/cnblogs_com/xiaobingqianrui/1185116/o_Image%201.png"
  157. }
  158.  
  159. Button
  160. {
  161. id:openBtn
  162. width: 100;
  163. height: 40;
  164. text: "Open";
  165. anchors.top:imageLabel.bottom
  166. anchors.topMargin: 10;
  167. anchors.left: parent.left
  168. anchors.leftMargin: 10;
  169. onClicked:fileDialog.open();
  170. }
  171.  
  172. Label
  173. {
  174. id:pathLabel;
  175. text: "Hello world"
  176. font.pixelSize: 22
  177. font.italic: true
  178. color: "steelblue"
  179.  
  180. anchors.top:imageLabel.bottom
  181. anchors.topMargin: 10;
  182. anchors.left: openBtn.right
  183. anchors.leftMargin: 10
  184. }
  185.  
  186. FileDialog
  187. {
  188. id:fileDialog
  189. title: "please choose a file"
  190. nameFilters: ["Image Files (*.jpg *.png *.gif)"]
  191. onAccepted:
  192. {
  193. imageLabel.source=fileDialog.fileUrl;
  194. console.log(fileDialog.fileUrl);
  195. var imageFile = new String(fileDialog.fileUrl);
  196. pathLabel.text=imageFile.slice(8);
  197. }
  198. }
  199. }*/

二 对象的方式实现在QML中使用C++对象

1. 注册属性

  1. viewer.rootContext()->setContextProperty("colorMaker", new ColorMaker);

2. 在QML中使用关联到的C++对象的属性

  一旦调用setContextProperty()导出了属性,就可以在QML中使用了,不需要import语句

  1. import QtQuick 2.2
  2. import QtQuick.Window 2.2
  3. import QtQuick.Controls 1.4
  4. import QtQuick.Controls.Styles 1.4
  5. import QtQuick.Dialogs 1.3
  6. import QtQml 2.11
  7. //import an.qt.ColorMaker 1.0
  8.  
  9. Rectangle
  10. {
  11. width: ;
  12. height: ;
  13. Text {
  14. id: timeLabel;
  15. anchors.left: parent.left;
  16. anchors.leftMargin: ;
  17. anchors.top : parent.top;
  18. anchors.topMargin: ;
  19. font.pixelSize: ;
  20. }
  21.  
  22. /* ColorMaker
  23. {
  24. id:colorMaker;
  25. color:Qt.green;
  26. }*/
  27.  
  28. Rectangle
  29. {
  30. id:colorRect;
  31. anchors.centerIn: parent;
  32. width: ;
  33. height: ;
  34. color: "blue";
  35. }
  36.  
  37. Button
  38. {
  39. id:start;
  40. text:"start";
  41. anchors.left: parent.left;
  42. anchors.leftMargin: ;
  43. anchors.bottom: parent.bottom;
  44. anchors.bottomMargin: ;
  45. onClicked:
  46. {
  47. console.log("start onClicked");
  48. colorMaker.start();
  49. }
  50. }
  51.  
  52. Button
  53. {
  54. id:stop;
  55. text:"stop";
  56. anchors.left: start.right;
  57. anchors.leftMargin: ;
  58. anchors.bottom: start.bottom;
  59. anchors.bottomMargin: ;
  60. onClicked:
  61. {
  62. colorMaker.stop();
  63. }
  64. }
  65.  
  66. function changeAlgorithm(button, algorithm)
  67. {
  68. switch(algorithm)
  69. {
  70. case :
  71. button.text = "RandomRGB"
  72. break;
  73. case :
  74. button.text ="RandomRed";
  75. break;
  76. case :
  77. button.text ="RandomGreen";
  78. break;
  79. case :
  80. button.text ="RandomBlue";
  81. break;
  82. case :
  83. button.text ="LinearIncrease";
  84. break;
  85. }
  86. }
  87.  
  88. Button
  89. {
  90. id:colorAlgorithm;
  91. text:"RandomRGB";
  92. anchors.left:stop.right;
  93. anchors.leftMargin: ;
  94. anchors.bottom: stop.bottom;
  95. onClicked:
  96. {
  97. var algorithm = (colorMaker.alorithm() + ) % ;
  98. changeAlgorithm(colorAlgorithm,algorithm);
  99. colorMaker.serAlgorithm(algorithm);
  100. }
  101. }
  102. Button
  103. {
  104. id:quit
  105. text:"quit"
  106. anchors.left: colorAlgorithm.right;
  107. anchors.leftMargin: ;
  108. anchors.bottom: colorAlgorithm.bottom;
  109. onClicked:
  110. {
  111. Qt.quit();
  112. }
  113. }
  114.  
  115. Component.onCompleted:
  116. {
  117. colorMaker.color = Qt.rgba(,,,);
  118. //colorMaker.serAlgorithm(colorMaker.LinearIcrease);
  119. colorMaker.serAlgorithm();
  120. changeAlgorithm(colorAlgorithm,colorMaker.alorithm());
  121. }
  122.  
  123. Connections
  124. {
  125. target: colorMaker;
  126.  
  127. onCurrentTime:
  128. {
  129. timeLabel.text = strTime;
  130. console.log("onCurrentTime");
  131. // timeLabel.color = colorMaker.timeColor;
  132. }
  133. }
  134.  
  135. Connections
  136. {
  137. target: colorMaker;
  138. onColorChanged:
  139. {
  140. colorRect.color = color;
  141. }
  142. }
  143. }

QT之在QML中使用C++类和对象的更多相关文章

  1. 在 QML 中使用 C++ 类和对象

    Qt Quick 技术的引入,使得你能够快速构建 UI ,具有动画.各种绚丽效果的 UI 都不在话下.但它不是万能的,也有很多局限性,原来 Qt 的一些技术,比如低阶的网络编程如 QTcpSocket ...

  2. 危险代码:如何使用Unsafe操作内存中的Java类和对象

    危险代码:如何使用Unsafe操作内存中的Java类和对象—Part1 危险代码:如何使用Unsafe操作内存中的Java类和对象—Part2 危险代码:如何使用Unsafe操作内存中的Java类和对 ...

  3. 如何在JavaScript中手动创建类数组对象

    前言 关于什么是js的类数组对象这里不再赘述.可以参考这个链接,还有这里. js中类数组对象很多,概念简单的讲就是看上去像数组,又不是数组,可以使用数字下标方式访问又没有数组方法. 例: argume ...

  4. C++中如何定义类和对象?

    在C++语言中,对象的类型被称为类,类代表了某一批对象的共性和特征. 类是对象的抽象,而对象是类的具体实例.如同C中的结构体一样,我们要先定义一个结构体,再使用结构体去定义一个变量.同一个结构体可以定 ...

  5. C++类继承中,基类/当前对象属性/当前对象的构造顺序

    [1]中提到,规范的派生类构造函数三个要点: 首先创建基类对象 应通过成员初始化列表,创建基类对象 应该初始化本派生类新增的成员变量 那在构造派生类实例的过程中,其基类(以及多继承的时候多个基类)/当 ...

  6. java开发中的常见类和对象-建议阅读时间3分钟

    1.Dao 数据访问对象 此对象用于访问数据库.实现类一般用于用于操作数据库! 一般操作修改,添加,删除数据库操作的步骤很相似,就写了一个公共类DAO类 ,修改,添加,删除数据库操作时 直接调用公共类 ...

  7. 什么是“类数组对象”,在jquer中怎样将类数组对象转换为数组对象

    类数组对象的定义: 所谓"类数组对象"就是一个常规的Object对象,如$("div")但它和数组对象非常相似:具备length属性, 并以0.1.2.3……等 ...

  8. 在qml中使用model给委托对象MapPolylIne的path属性赋值。

    遇到两个崩溃的问题. 1.A线程中给赋值了变量 listA, 线程B中使用函数Add(QList<GeoPath> &list),由于在其函数中调用了list.at(index), ...

  9. python中面向对象_类_对象的概念与定义

    1. 面向对象的概念,面向对象是一种编程思想. 是对现实世界中一类事物的抽象,在编程中可以理解为是一种建立现实世界事物的模型 2.  面向对象和面向过程的区别: 面向过程关注的是完成工作的步骤. 面向 ...

随机推荐

  1. 安装Hadoop 1.1.2 (二 安装配置SSH)

    1 查找SSH  yum search ssh 2 如果没有安装, yum install openssh.x86_64 4 直接运行  ssh-keygen -t dsa -P '' -f /roo ...

  2. 2218 补丁vs错误

    2218 补丁vs错误 1999年CTSC国家队选拔赛  时间限制: 1 s  空间限制: 64000 KB  题目等级 : 大师 Master 题解       题目描述 Description 错 ...

  3. <转载> 为什么在Python里推荐使用多进程而不是多线程?

    经常我们会听到老手说:“Python下多线程是鸡肋,推荐使用多进程!”,但是为什么这么说呢?                要知其然,更要知其所以然.所以有了下面的深入研究: 首先强调背景:     ...

  4. 如何将gedit变成c++编译器

    本蒟蒻的第一篇文章,分享一下神佬教我的好东西 ——将Ubuntu 16.04上gedit变为编译器! 1° 新建文档.然后点击编辑,打开首选项. 2° 勾选外部工具,然后退出.打开工具,选择Manag ...

  5. go语言之面向对象一

    在Go语言中, 你可以给任意类型(包括内置类型,但不包括指针类型)添加相应的办法.示例如下: type Integer int func (a Integer) Less(b Integer) boo ...

  6. centos7 使用 maven

    http://www.cnblogs.com/jackluo/archive/2013/02/06/2901816.html

  7. 只需两步删除 node_modules

    peng@PENG-PC /E/_My_File_____/home/learn/web_qianduan/mithril-demo/demo2/mithril -demo $ npm install ...

  8. 关于VMAX中存储资源池(SRP)

    Storage Resource Pool中的相关元素 SRP由一个或多个数据池组成,这些数据池包含了预配置的数据(或TDAT)设备,可为创建和呈现给主机与应用程序的精简设备(TDEVS) 提供存储. ...

  9. R中常用数据挖掘算法包

    数据挖掘主要分为4类,即预测.分类.聚类和关联,根据不同的挖掘目的选择相应的算法.下面对R语言中常用的数据挖掘包做一个汇总: 连续因变量的预测: stats包 lm函数,实现多元线性回归 stats包 ...

  10. Oracle数据库体系结构(3)数据库进程

    一.Oracle进程概述 在oracle中进程分为用户进程(User Process).服务器进程(server process)和后天进程3种. 1.用户进程:当用户连接到数据库执行一个应用程序是, ...