C++和QML混合编程

  • 一、QML访问C++方法

  1. Qt元对象系统中注册C++类,在QML中实例化、访问。
  2. C++中实例化并设置为QML上下文属性,在QML中直接使用。

           比较:方法1可以使C++类在QML中作为一个数据类型,例如函数参数类型或属性类型,也可以使用其枚举类型、单例等,功能更强大。

  • 二、QML访问C++条件

  1. 派生自QObject类或QObject类的子类
  2. 使用Q_OBJECT宏
  • 三、QML访问C++举例

                     使用方法1

信号与槽

 

#ifndef GEMINI_H  
#define GEMINI_H  
#include <QObject>  
#include <QDebug>  
class Gemini : public QObject  
{  
    Q_OBJECT  
signals:    //1、先定义“信号”
    void begin();   
public slots:  //1、先定义“槽”
    void doSomething() {  
        qDebug() << "Gemini::doSomething() called";  
    }  
};  
#endif 

 

#include <QGuiApplication>  
#include <QQmlApplicationEngine>  
#include <QtQml>  
#include <Gemini.h>  
int main(int argc, char *argv[])  
{  
    QGuiApplication app(argc, argv);  
    qmlRegisterType<Gemini>("Union.Lotto.Gemini", 1, 0, "Gemini");  //一.注册c++类
    QQmlApplicationEngine engine;  
    engine.load(QUrl(QStringLiteral("qrc:///main.qml")));  
    return app.exec();  
}
import QtQuick 2.2  
import QtQuick.Window 2.1  
import Union.Lotto.Gemini 1.0  //二.导入
Window {  
    visible: true  
    width: 360; height: 360  
    title: "Union Lotto Game"  
    color: "white"  
    MouseArea {  
        anchors.fill: parent  
        onClicked: {  
            gemini.begin()  //2.调用类信号
        }  
    }  
    Gemini {  
        id: gemini  
        onBegin: doSomething()  //2.调用类槽
    }  
}

 

 

                2、枚举类型

#ifndef GEMINI_H  
#define GEMINI_H  

#include <QObject>  
#include <QDebug>  
class Gemini : public QObject  
{  
    Q_OBJECT  
    Q_ENUMS(BALL_COLOR)  //1、先定义。枚举类型在QML中使用,就用到了Q_ENUMS()宏
public:  
    Gemini() : m_ballColor(BALL_COLOR_YELLOW) {  
        qDebug() << "Gemini::Gemini() called";  
    }  
    enum BALL_COLOR {  
        BALL_COLOR_YELLOW,  
        BALL_COLOR_RED,  
        BALL_COLOR_BLUE,  
        BALL_COLOR_ALL  
    };  
signals:  
    void begin();  
public slots:  
    void doSomething(BALL_COLOR ballColor) {  
        qDebug() << "Gemini::doSomething() called with" << ballColor;  
        if(ballColor != m_ballColor) {  
            m_ballColor = ballColor;  
            qDebug() << "ball color changed";  
        }  
    }  
private:  
    BALL_COLOR m_ballColor;  
};  
#endif 
import QtQuick 2.2  
import QtQuick.Window 2.1  
import Union.Lotto.Gemini 1.0  
Window {  
    visible: true  
    width: 360; height: 360  
    title: "Union Lotto Game"  
    color: "white"  
    MouseArea {  
        anchors.fill: parent  
        onClicked: {  
            gemini.begin()  
        }  
    }  
    Gemini {  
        id: gemini  
        onBegin: doSomething(Gemini.BALL_COLOR_RED)  //2.调用,在QML中使用枚举类型的方式是<CLASS_NAME>.<ENUM_VALUE>
    }  
}

 

                3、成员函数

 

#ifndef GEMINI_H  
#define GEMINI_H  

#include <QObject>  
#include <QDebug>  
class Gemini : public QObject  
{  
    Q_OBJECT  
    Q_ENUMS(BALL_COLOR)  
public:  
    Gemini() : m_ballColor(BALL_COLOR_YELLOW) {  
        qDebug() << "Gemini::Gemini() called";  
    }  
    enum BALL_COLOR {  
        BALL_COLOR_YELLOW,  
        BALL_COLOR_RED,  
        BALL_COLOR_BLUE,  
        BALL_COLOR_ALL  
    };  
    Q_INVOKABLE void stop() {  //1、定义。访问的前提是public或protected成员函数,且使用Q_INVOKABLE宏
        qDebug() << "Gemini::stop() called";  
    }  
signals:  
    void begin();  
public slots:  
    void doSomething(BALL_COLOR ballColor) {  
        qDebug() << "Gemini::doSomething() called with" << ballColor;  
        if(ballColor != m_ballColor) {  
            m_ballColor = ballColor;  
            qDebug() << "ball color changed";  
        }  
    }  
private:  
    BALL_COLOR m_ballColor;  
};  
#endif 

 

import QtQuick 2.2  
import QtQuick.Window 2.1  
import Union.Lotto.Gemini 1.0  
Window {  
    visible: true  
    width: 360; height: 360  
    title: "Union Lotto Game"  
    color: "white"  
    MouseArea {  
        anchors.fill: parent  
        onClicked: {  
            gemini.begin()  
            gemini.stop()  //2、调用,在QML中访问C++的成员函数的形式是<id>.<method>
        }  
    }  
    Gemini {  
        id: gemini  
        onBegin: doSomething(Gemini.BALL_COLOR_RED)  
    }  
}

 

 

                4、C++类的属性

 

#ifndef GEMINI_H  
#define GEMINI_H  

#include <QObject>  
#include <QDebug>  
class Gemini : public QObject  
{  
    Q_OBJECT  
    Q_ENUMS(BALL_COLOR)  
    Q_PROPERTY(unsigned int ballNumber READ ballNumber WRITE setBallNumber NOTIFY ballNumberChanged)  //1、定义,Q_PROPERTY()宏,用来在QObject派生类中声明属性。
public:  
    Gemini() : m_ballColor(BALL_COLOR_YELLOW), m_ballNumber(0) {  
        qDebug() << "Gemini::Gemini() called";  
    }  
    enum BALL_COLOR {  
        BALL_COLOR_YELLOW,  
        BALL_COLOR_RED,  
        BALL_COLOR_BLUE,  
        BALL_COLOR_ALL  
    };  
    unsigned int ballNumber() const {  
        return m_ballNumber;  
    }  
    void setBallNumber(const unsigned int &ballNumber) {  
        if(ballNumber != m_ballNumber) {  
            m_ballNumber = ballNumber;  
            emit ballNumberChanged();  
        }  
    }  
    Q_INVOKABLE void stop() {  
        qDebug() << "Gemini::stop() called";  
    }  
signals:  
    void begin();  
    void ballNumberChanged();  
public slots:  
    void doSomething(BALL_COLOR ballColor) {  
        qDebug() << "Gemini::doSomething() called with" << ballColor;  
        if(ballColor != m_ballColor) {  
            m_ballColor = ballColor;  
            qDebug() << "ball color changed";  
        }  
    }  
private:  
    BALL_COLOR m_ballColor;  
    unsigned int m_ballNumber;  
};  
#endif

 

import QtQuick 2.2  
import QtQuick.Window 2.1  
import Union.Lotto.Gemini 1.0  
Window {  
    visible: true  
    width: 360; height: 360  
    title: "Union Lotto Game"  
    color: "white"  
    MouseArea {  
        anchors.fill: parent  
        onClicked: {  
            gemini.begin()  
            gemini.stop()  
            gemini.ballNumber = 10  //2、调用,Gemini类中的ballNumber属性可以在QML中访问、修改,访问时调用了ballNumber()函数,
// 修改时调用了setBallNumber()函数,同时还发送了一个信号来自动更新这个属性值。
} } Gemini { id: gemini onBegin: doSomething(Gemini.BALL_COLOR_RED) onBallNumberChanged: console.log(
"new ball number is", ballNumber) // 10 Component.onCompleted: console.log("default ball number is", ballNumber) // 0 } }

 

备注:1、参考网址:https://zhuanlan.zhihu.com/p/633999343

           2、本文只为个人学习笔记,其他第三方可以任意使用。

 

热门相关:我寄人间   山神   重生之我的书记人生   现代隐士高手   我有一张沾沾卡