QML和C++混合编程

QML和C++混合编程

推荐博客:
http://blog.csdn.net/foruok/article/details/32698603
http://blog.csdn.net/zzti_erlie/article/details/53008987
https://blog.csdn.net/qq_33154343/article/details/79364846

编译环境: win10专业版 Qt Creator 4.5.2 based on Qt 5.9.5

工程创建步骤:New Project–>Application–>Qt Quick Application-Empty
在这里插入图片描述
工程名称:qml_mixed_Cpp
在这里插入图片描述
qml_mixed_Cpp.pro

QT += quick
CONFIG += c++11

# The following define makes your compiler emit warnings if you use
# any feature of Qt which as been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS

# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0

SOURCES += main.cpp \
    colormaker.cpp

RESOURCES += qml.qrc

# Additional import path used to resolve QML modules in Qt Creator's code model
QML_IMPORT_PATH =

# Additional import path used to resolve QML modules just for Qt Quick Designer
QML_DESIGNER_IMPORT_PATH =

# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target

HEADERS += \
    colormaker.h

main.cpp

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include "colormaker.h"

int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
    QGuiApplication app(argc, argv);
    /*
     * 注册一个非单例QML类型, 然后就可以在QML里面调用了.
     * qmlRegisterType()的第一个参数uri,指定唯一的包名
     * 一是可以避免名字冲突,二是可以把多个相关类聚合到一个包中方便引用
     * 比如我们常写的这句“import QtQuick.Controls 1.1”, 其中的“QtQuick.Controls”就是包名uri,“1.1”是版本(versionMajor和versionMinor的组合)
     * qmlName则是QML中可以使用的类名
    */
    qmlRegisterType<ColorMaker>("an.qt.ColorMaker",1,0,"ColorMaker");//包名:an.qt.ColorMaker,版本:1.0 类名:ColorMaker
    //上面代码将ColorMaker类注册为QML类ColorMaker,主版本1,次版本0,
    QQmlApplicationEngine engine;
    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
    if (engine.rootObjects().isEmpty())
        return -1;

    return app.exec();
}

colormaker.h

#ifndef COLORMAKER_H
#define COLORMAKER_H

#include <QObject>
#include <QColor>
#include <QTimerEvent>

//实现可以导出的C++类
class ColorMaker : public QObject
{
    Q_OBJECT
    //导出的类定义了想在QML文件中使用的枚举类型,使用Q_ENUMS宏将该枚举类型注册到元对象系统中
    Q_ENUMS(GenerateAlgorithm)
    //Q_PROPERTY宏用来定义可通过元对象系统访问的属性,通过它定义的属性,可以在QML文件中访问、修改,也可以在属性变化时发射特定的信号
    //注意:使用Q_PROPERTY宏,该类必须是QObject的后裔,必须先在类首使用Q_OBJECT宏
    //Q_PROPERTY(type name READ name WRITE setName NOTIFY nameChanged)
    /*
    READ--声明一个读取属性的函数,该函数一般没有参数,返回定义的属性
    WRITE---可选配置。声明一个设定属性的函数,它指定的函数没有返回值,只能有一个与属性类型匹配的参数。
    NOTICE---可选配置。给属性关联一个信号(该信号必须是已经在类中声明过的),当属性的值发生变化时就会触发该信号。信号的参数一般就是你定义的属性。
    */
    Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged)
    Q_PROPERTY(QColor timeColor READ timeColor)

public:
    explicit ColorMaker(QObject *parent = nullptr);
    ~ColorMaker();
    //枚举变量--5种颜色算法
    enum GenerateAlgorithm{
        RandomRGB,
        RandomRed,
        RandomGreen,
        RandomBlue,
        LinearIncrease //线性渐变
    };
    /*
    通过把类成员函数声明为const 以表明它们不修改类对象。 任何不会修改数据成员的函数都应该声明为const类型。
    如果在编写const成员函数时,不慎修改了数据成员,或者调用了其它非const成员函数,
    编译器将指出错误,这样做的好处是提高程序了的健壮性。
    */
    QColor color() const;//常量成员函数---指明不可修改成员变量的值
    void setColor(const QColor & color);
    QColor timeColor() const;
    //在定义一个类的成员函数时, 使用Q_INVOKABLE宏来修饰,就可以让该方法被元对象系统调用。这个宏必须放在返回类型前面
    Q_INVOKABLE GenerateAlgorithm getAlgorithm() const; //返回类型为GenerateAlgorithm,这是一个算法函数
    Q_INVOKABLE void setAlgorithm(GenerateAlgorithm algorithm);//设置使用那种颜色计算方法
signals:
    void colorChanged(const QColor & color);//改变颜色的信号
    void currentTimer(const QString &strTime);//当前时间的信号
public slots:
    void start();
    void stop();

protected:
    void timerEvent(QTimerEvent *event);//时间事件
private:
    GenerateAlgorithm m_algorithm;
    QColor myColor;//现在的颜色
    int m_nColorTimer;//定时器的ID
};
#endif // COLORMAKER_H

colormaker.cpp

#include "colormaker.h"
#include <QTimerEvent>
#include <QDateTime>

ColorMaker::ColorMaker(QObject *parent)
    : QObject(parent)
    ,m_algorithm(RandomRGB) //初始化一个随机的颜色算法
    ,myColor(Qt::black) //初始化赋值为黑色
    ,m_nColorTimer(0)
{
    qsrand(QDateTime::currentDateTime().toTime_t());
}

ColorMaker::~ColorMaker()
{

}

//调用该函数,确定设置颜色顺便会发射颜色改变的信号
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()*2;
    int b = time.second()*4;
    return QColor::fromRgb(r,g,b);//颜色根据当前时间来生成
}

ColorMaker::GenerateAlgorithm ColorMaker::getAlgorithm() const
{
    return m_algorithm;
}
void ColorMaker::setAlgorithm(GenerateAlgorithm algorithm)
{
    m_algorithm = algorithm;//赋值给类成员
}

void ColorMaker::start()//开启定时器
{
    if(m_nColorTimer == 0)
    {
        m_nColorTimer = startTimer(100);//使用一个周期为1000毫秒的定时器来产生颜色
    }
}
void ColorMaker::stop(){
    if(m_nColorTimer > 0)
    {
        killTimer(m_nColorTimer);//停止定时器的使用
        m_nColorTimer = 0;
    }
}

//timerEvent事件消息
void ColorMaker::timerEvent(QTimerEvent *event)
{
    static unsigned char u8_cnt=0;
    if(event->timerId() == m_nColorTimer)
    {
        switch (m_algorithm) {
        case RandomRGB:
            myColor.setRgb(qrand()%255, qrand()%255, qrand()%255);
            break;
        case RandomRed:
            //myColor.setRed(qrand()%255);
            myColor.setRed(u8_cnt);  u8_cnt>254?u8_cnt=0:u8_cnt+=10;
            break;
        case RandomGreen:
            myColor.setGreen(u8_cnt); u8_cnt>254?u8_cnt=0:u8_cnt+=10;
            break;
        case RandomBlue:
            myColor.setBlue(u8_cnt);u8_cnt>254?u8_cnt=0:u8_cnt+=10;
            break;
        case LinearIncrease:
        {
            int r = myColor.red() + 10;
            int g = myColor.green() + 10;
            int b = myColor.blue() + 10;
            myColor.setRgb(r%255,g%255,b%255);
        }
            break;
        default:
            break;
        }
        //定时器触发时根据算法计算新的颜色值,发射colorChanged信号,同时也发送一个currentTime信号
        emit colorChanged(myColor);
        emit currentTimer(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"));
    }
    else
    {
        QObject::timerEvent(event);
    }
}

main.qml

import QtQuick 2.7
import QtQuick.Controls 2.0  //控制版本
import QtQuick.Layouts 1.0  //布局版本
import an.qt.ColorMaker 1.0  //导入自定义的C++类

ApplicationWindow {
    visible: true
    width: 640
    height: 480
    title: qsTr("qml与C++混合编程-20200612")
    Rectangle{
        width: 360;
        height: 360;
        //显示时间文本的label
        Text{
            id:timeLabel;
            anchors.left: parent.left;
            anchors.leftMargin: 4;
            anchors.top:parent.top;
            anchors.topMargin: 4;
            font.pixelSize: 26;
        }

        //这里调用了C++类,创建了一个供QML使用的C++对象
        ColorMaker{
            id:colorMaker;
            color:Qt.green;
        }
        //中间显示颜色变化的矩形
        Rectangle{
            id:colorRect;
            anchors.centerIn: parent;
            width: 200;
            height: 200;
            color: "blue";
            Text{
                id:str_color_algorithm;
                anchors.fill: colorRect;
                anchors.centerIn: colorRect;
                text:"sdasdasd";
            }
        }
        //开始按钮
        Button{
            id:start;
            text:"start";
            anchors.left:parent.left;
            anchors.leftMargin: 4;
            anchors.bottom: parent.bottom;
            anchors.bottomMargin: 4;
            onClicked: {
                colorMaker.start();
            }
        }
        //结束按钮
        Button{
            id:stop;
            text:"stop";
            anchors.left: start.right;
            anchors.leftMargin: 4;
            anchors.bottom: start.bottom;
            onClicked: {
                colorMaker.stop();
            }
        }


        //改变颜色算法按钮
        Button{
            id:bt_colorAlgorithm;
            text:"RGB";
            anchors.left: stop.right;
            anchors.leftMargin: 4;
            anchors.bottom: start.bottom;
            onClicked: {
                var color_algorithm = (colorMaker.getAlgorithm()+1)%5;
                changeAlgorithm(color_algorithm);
                //str_color_algorithm.text = color_algorithm.toString();
                colorMaker.setAlgorithm(color_algorithm);
            }
            function changeAlgorithm(algorithm){
                switch(algorithm)
                {
                case 0:
                    str_color_algorithm.text = "RandomRGB";
                    break;
                case 1:
                    str_color_algorithm.text = "RandomRed";
                    break;
                case 2:
                    str_color_algorithm.text = "RandomGreen";
                    break;
                case 3:
                    str_color_algorithm.text = "RandomBlue";
                    break;
                case 4:
                    str_color_algorithm.text = "LinearIncrease";
                    break;
                }
            }
        }
        //JavaScript函数


        //退出按钮
        Button{
            id:quit;
            text:"quit";
            anchors.left: bt_colorAlgorithm.right;
            anchors.leftMargin: 4;
            anchors.bottom: start.bottom;
            onClicked: {
                Qt.quit();
            }
        }

        Component.onCompleted: {
            colorMaker.color = Qt.rgba(0,180,120,255);
            colorMaker.setAlgorithm(ColorMaker.LinearIncrease);
            str_color_algorithm.text = "LinearIncrease";
        }
        //关联控件colorMaker和槽函数onCurrentTimer
        Connections{
            target: colorMaker;  //接收事件的对象
            onCurrentTimer:{  //接收事件时的处理函数
                timeLabel.text = strTime;  //strTime是currentTimer信号里的参数
                timeLabel.color = colorMaker.timeColor;
            }
        }
        Connections{
            target: colorMaker;
            onColorChanged:{
                colorRect.color = color;
            }
        }
    }
}
本文适合于对Qt Quick有基本了解的读者。首先回答一个比较常会被问到的问题:什么是QML,它与Quick的关系是什么? Qt Quick是Qt User Interface Creation Kit的缩写,而QMLQt Quick最重要的组成部分,Qt Quick结合了如下技术: 组件集合,其中大部分是关于图形界面的 基于JavaScript陈述性语言:QMLQt Meta-Object Language的缩写) 用于管理组件并与组件交互的C++ API - QtDeclarative模块 言归正传:通过Qt Creator,我们可以轻松生成一个Qt Quick的应用工程,从而为QML生成应用程序框架。具体操作详见:创建qt quick (qml) 应用程序。 C++QML的交互是通过注册C++对象给QML环境得以实现的: 在C++实现中,非可视化的型别均为QObject的子类,可视化的类型均为QDeclarativeItem的子类。注意:QDeclarativeItem等同于QML的Item类。 如果用户想要定义自己的型别,做法如下: 在C++中,实现派生于QObject或QDeclarativeItem的子类,它是新定义item的实体对象; 在C++中,将1中实现的新item类型注册给QML; 在QML中,导入含有1中定义的新item的模块; 在QML中,向使用标准的item一样使用新定义的item 现举例说明,我们现尝试使用用Qt C++实现的MyButton对象(如下qml代码),它有自己的属性、方法以及信号的handler。用法如下(它与使用其它标准的QML item一样),所需要做的是 需要导入包含MyButton的对应模块名称及其版本“MyItems 1.0 ”。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值