C++和QML混合编程
-
一、QML访问C++方法
- Qt元对象系统中注册C++类,在QML中实例化、访问。
- C++中实例化并设置为QML上下文属性,在QML中直接使用。
比较:方法1可以使C++类在QML中作为一个数据类型,例如函数参数类型或属性类型,也可以使用其枚举类型、单例等,功能更强大。
-
二、QML访问C++条件
- 派生自QObject类或QObject类的子类
- 使用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、本文只为个人学习笔记,其他第三方可以任意使用。