Qt5.8 QML和C++混合编程的两种方式(附带源码)

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

上手敲一下,很快就能理解 
             Qt5.8 QML和C++混合编程的两种方式(附带源码)_第1张图片 

点击开始,中间的图形开始变化,上面显示时间,点击停止,不再变化,点击RGB,应用这个算法,按钮显示为下一个算法,退出按钮退出程序


************************************************************************************************************************************************************************************************************************************************

1.C++ 中实现一个类,注册到 QML 环境中, QML 环境中使

用该类型创建对象

QML中使用C++对象

(1)实现可以导出的C++类 

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

 Qt5.8 QML和C++混合编程的两种方式(附带源码)_第2张图片


******************************************************************************************************************


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

创建的步骤如下:

Qt5.8 QML和C++混合编程的两种方式(附带源码)_第3张图片


你可能感兴趣的:(Qt)