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;
            }
        }
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章