Qt5.8 QML和C++混合编程的两种方式(附带源码)
编译环境:win10 专业版 Qt5.8
Qt 提供了两种在 QML 环境中使用 C++ 对象的方式:
推荐博客:http://blog.csdn.net/foruok/article/details/32698603
和 http://blog.csdn.net/zzti_erlie/article/details/53008987
上手敲一下,很快就能理解点击开始,中间的图形开始变化,上面显示时间,点击停止,不再变化,点击RGB,应用这个算法,按钮显示为下一个算法,退出按钮退出程序
************************************************************************************************************************************************************************************************************************************************
1.C++ 中实现一个类,注册到 QML 环境中, QML 环境中使
用该类型创建对象
colormaker.h
#ifndef COLORMAKER_H
#define COLORMAKER_H
#include
#include
#include
class ColorMaker : public QObject
{
Q_OBJECT
// 如果你要导出的类定义了想在 QML 中使用枚举类型,可以使用 Q_ENUMS 宏将该枚举注册到元对象系统中。
Q_ENUMS(generate)
//Q_PROPERTY 宏用来定义可通过元对象系统访问的属性,通过它定义的属性,可以在 QML 中访问、修改,也可以在属性变化时发射特定的信号。
//READ 声明一个读取属性的函数,该函数一般没有参数,返回定义的属性。
//WRITE [可选]声明一个设定属性的函数。它指定的函数,只能有一个与属性类型匹配的参数,必须返回 void 。
//NOTIFY [可选]给属性关联一个信号(该信号必须是已经在类中声明过的),当属性的值发生变化时就会触发该信号。信号的参数,一般就是你定义的属性。
Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged)
Q_PROPERTY(QColor timeColor READ timeColor )
public:
explicit ColorMaker(QObject *parent = 0);
//枚举该变量 (5中颜色的算法)
enum generate{
randomRGB,
randomRed,
randomGreen,
randomBlue,
increase //(颜色变化算法为)直线增长模式
};
QColor color() const;
void setColor(const QColor &color);
QColor timeColor() const;
//在定义一个类的成员函数时使用 Q_INVOKABLE 宏来修饰,就可以让该方法被元对象系统调用。这个宏必须放在返回类型前面。
Q_INVOKABLE generate algorithm() const; //返回类型为枚举类型GenerateAlgorithm; 这是一个算法函数
Q_INVOKABLE void setAlgouthm(generate algorithm); //设置为具体使用哪一个颜色的算法
signals:
//定义colorChanged() / currentTime() 两个信号
void colorChanged(const QColor &color); //颜色改变的信号
void currentTimer(const QString &strTime); //当前时间的信号
public slots:
//定义了 start() / stop() 两个槽
void start();
void stop();
protected:
void timerEvent(QTimerEvent *event); //时间事件
private:
generate myGenerate; //具体使用的哪一种算法
QColor myColor; //现在的颜色
int colorTimer; //定时器的ID
};
#endif // COLORMAKER_H
colormaker.cpp
#include "colormaker.h"
#include
#include
ColorMaker::ColorMaker(QObject *parent)
: QObject(parent)
, myGenerate(randomRGB) //初始化一个随机的颜色算法
, myColor(Qt::black) //初始化赋值为黑色
, colorTimer(0)
{
qsrand(QDateTime::currentDateTime().toTime_t());
}
//单纯的调用该函数, 确定设置颜色顺便会发射颜色改变的信号
QColor ColorMaker::color() const
{
return myColor;
}
//颜色由当前时间作为参数来生成
void ColorMaker::setColor(const QColor &color)
{
myColor = color;
emit colorChanged(myColor);
}
//颜色由当前时间作为参数来生成
QColor ColorMaker::timeColor() const
{
QTime time = QTime::currentTime(); //获取当前现在的时间
int r = time.hour();
int g = time.minute();
int b = time.second();
return QColor::fromRgb(r, g, b);
}
//传送出去一个(算法)的值 [确定是使用哪一种算法,RGB? Green? Red? Blue? ]
ColorMaker::generate ColorMaker::algorithm() const
{
return myGenerate;
}
//赋值给类成员
void ColorMaker::setAlgouthm(ColorMaker::generate algorithm)
{
myGenerate = algorithm;
}
//启动时间
void ColorMaker::start()
{
if(colorTimer == 0)
{
colorTimer = startTimer(1000);
}
}
//停止计时器的使用
void ColorMaker::stop()
{
if(colorTimer > 0)
{
killTimer(colorTimer); //终止计时器,销毁
colorTimer = 0;
}
}
//timerEvent事件消息
void ColorMaker::timerEvent(QTimerEvent *event)
{
if(event->timerId() == colorTimer)
{
switch (myGenerate) {
case randomRGB:
myColor.setRgb(qrand()%255, qrand()%255, qrand()%255);
break;
case randomRed:
myColor.setRed(qrand()%255);
break;
case randomGreen:
myColor.setGreen(qrand()%255);
break;
case randomBlue:
myColor.setBlue(qrand()%255);
break;
default:
{
int r = myColor.red() + 10;
int g = myColor.green() + 10;
int b = myColor.blue() + 10;
myColor.setRgb(r%255, g%255, b%255);
}
break;
}
//发射这两个信号
emit colorChanged(myColor);
emit currentTimer(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"));
}
else
{
timerEvent(event);
}
}
main.cpp
#include
#include
#include
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
// 注册一个 QML 类型 ;注册一个单例类型,然后就可以在qml里面调用了
//qmlRegisterType() 的第一个参数 uri ,让你指定一个唯一的包名,类似 Java 中的那种,
//一是用来避免名字冲突,而是可以把多个相关类聚合到一个包中方便引用。
//比如我们常写这个语句 "import QtQuick.Controls 1.1" ,其中的 "QtQuick.Controls" 就是包名 uri ,而 1.1 则是版本,是 versionMajor 和 versionMinor 的组合。
//qmlName 则是 QML 中可以使用的类名。
qmlRegisterType("qt.an.colormaker", 1, 0, "ColorMaker"); //只增加了这一句
QQmlApplicationEngine engine;
engine.load(QUrl(QLatin1String("qrc:/main.qml")));
return app.exec();
}
main.qml
import QtQuick 2.7
import QtQuick.Controls 2.0 //控制版本
import QtQuick.Layouts 1.0 //布局版本
import qt.an.colormaker 1.0 //导入自定义的C++的类, 这是其自定义的包名和主、次版本号
ApplicationWindow {
visible: true
width: 640
height: 480
title: qsTr("2018_2_26_qml与C++混合编程")
Text {
id: timeLabel;
anchors.top: parent.top;
anchors.horizontalCenter: parent.horizontalCenter;
font.pixelSize: 40;
}
//在这里调用了C++类, 创建了一个介意供qml使用的C++对象
ColorMaker {
id: colorMaker;
}
//中间显示颜色变化的矩形
Rectangle {
id:colorRect;
anchors.centerIn: parent;
width: 300;
height: 300;
color: "Green";
}
//开始按钮
Button {
id: start;
text: "start";
anchors.left: parent.left;
anchors.bottom: parent.bottom;
anchors.leftMargin: 4;
anchors.bottomMargin: 4;
onClicked: {
colorMaker.start();
}
}
//结束按钮
Button {
id: stop;
text: "stop";
anchors.left: start.right;
anchors.bottom: parent.bottom;
anchors.leftMargin: 4;
anchors.bottomMargin: 4;
onClicked: {
colorMaker.stop();
}
}
//Javascript函数
function changetAlgorithm(button, algorithm) {
switch(algorithm)
{
case 0:
button.text = "RGB";
break;
case 1:
button.text = "Red";
break;
case 2:
button.text = "Green";
break;
case 3:
button.text = "Blue";
break;
default:
button.text = "increase";
break;
}
}
//颜色算法按钮
Button {
id: colorAlgorithm;
text: "RGB";
anchors.left: stop.right;
anchors.bottom: parent.bottom;
anchors.leftMargin: 4;
anchors.bottomMargin: 4;
onClicked: {
var algorithm = (colorMaker.algorithm() +1) % 5;
changetAlgorithm(colorAlgorithm, algorithm); //changetAlgorithm是后面的Javascript函数
colorMaker.setAlgouthm(algorithm);
}
}
//退出按钮
Button {
id: quit;
text: "quit";
anchors.left: colorAlgorithm.right;
anchors.bottom: parent.bottom;
anchors.leftMargin: 4;
anchors.bottomMargin: 4;
onClicked: {
Qt.quit();
}
}
//关联控件colorMaker 和 槽函数onCurrentTimer
Connections {
target: colorMaker; //接收事件的对象
onCurrentTimer: { //收到事件时的处理函数
timeLabel.text = strTime; //strTime从currentTimer里发送过来的
timeLabel.color = colorMaker.timeColor;
}
}
Connections {
target: colorMaker;
onColorChanged: {
colorRect.color = colorMaker.color;
}
}
}
项目名称:2018_2_26_qmlANDc
******************************************************************************************************************
2.在 C++ 中构造一个对象,将这个对象设置为 QML 的上下文
属性,在 QML 环境中直接使用改属性
colormaker.h 不变,和上面一样
colormaker.cpp 不变,和上面一样
main.cpp 有变化
#include
#include
#include
#include
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
engine.rootContext()->setContextProperty("colorMaker", new ColorMaker); //新增加的一句,用于注册可以被qml使用的C++对象
engine.load(QUrl(QLatin1String("qrc:/main.qml")));
return app.exec();
}
main.qml 有变化, 但是是只有两处需要注释掉
import QtQuick 2.7
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.0
//import qt.an.colormaker 1.0 //不需要导入这个包
ApplicationWindow {
visible: true
width: 640
height: 480
title: qsTr("2018_2_26_qml与C++混合编程")
Text {
id: timeLabel;
anchors.top: parent.top;
anchors.horizontalCenter: parent.horizontalCenter;
font.pixelSize: 40;
}
//不需要在这里创建这个对象了
// ColorMaker {
// id: colorMaker;
// }
Rectangle {
id:colorRect;
anchors.centerIn: parent;
width: 300;
height: 300;
color: "Green";
}
Button {
id: start;
text: "start";
anchors.left: parent.left;
anchors.bottom: parent.bottom;
anchors.leftMargin: 4;
anchors.bottomMargin: 4;
onClicked: {
colorMaker.start();
}
}
Button {
id: stop;
text: "stop";
anchors.left: start.right;
anchors.bottom: parent.bottom;
anchors.leftMargin: 4;
anchors.bottomMargin: 4;
onClicked: {
colorMaker.stop();
}
}
//Javascript函数
function changetAlgorithm(button, algorithm) {
switch(algorithm)
{
case 0:
button.text = "RGB";
break;
case 1:
button.text = "Red";
break;
case 2:
button.text = "Green";
break;
case 3:
button.text = "Blue";
break;
default:
button.text = "increase";
break;
}
}
Button {
id: colorAlgorithm;
text: "RGB";
anchors.left: stop.right;
anchors.bottom: parent.bottom;
anchors.leftMargin: 4;
anchors.bottomMargin: 4;
onClicked: {
var algorithm = (colorMaker.algorithm() +1) % 5;
//changetAlgorithm是上面的Javascript函数, 必须先定义,后使用
changetAlgorithm(colorAlgorithm, algorithm);
colorMaker.setAlgouthm(algorithm);
}
}
Button {
id: quit;
text: "quit";
anchors.left: colorAlgorithm.right;
anchors.bottom: parent.bottom;
anchors.leftMargin: 4;
anchors.bottomMargin: 4;
onClicked: {
Qt.quit();
}
}
Connections {
target: colorMaker;
onCurrentTimer: {
timeLabel.text = strTime;
timeLabel.color = colorMaker.timeColor;
}
}
Connections {
target: colorMaker;
onColorChanged: {
colorRect.color = colorMaker.color;
}
}
}
******************************************************************************************************************
源码链接:https://pan.baidu.com/s/1nwDc7l3 密码:jao1
创建的步骤如下: