【qml学习笔记】QML与C++的交互

QML与C++的交互

在QML中访问c++对象
  • 首先创建一个类,这个类需继承自QObject,必须有Q_OBJECT宏,并加入QML_ELEMENT宏,并且私有成员具有Q_PROPERTY宏(可通过ALT+ENTER快速设置)
cpp 复制代码
#include <QObject>
#include <QtQml>//注意 QML_ELEMENT 需要该头文件
class MyCppObj : public QObject
{
    Q_OBJECT
    QML_ELEMENT
public:
    explicit MyCppObj(QObject *parent = nullptr);
    int iValue() const;
    void setIValue(int newIValue);
    
    QString string() const;
    void setString(const QString &newString);
    //加入 Q_INVOKABLE宏的函数才可在QML端进行访问
    Q_INVOKABLE void func();
    
private:
    int m_iValue;
    QString m_string;
    
    Q_PROPERTY(int iValue READ iValue WRITE setIValue NOTIFY iValueChanged FINAL)
    Q_PROPERTY(QString string READ string WRITE setString NOTIFY stringChanged FINAL)
    
signals:
    void iValueChanged();
    void stringChanged();
};
  • 在cpp文件中对对象进行注册
cpp 复制代码
//一定要通过创建对象来定义我们自定义的obj,对象存在于qml端
qmlRegisterType<MyCppObj>("MyCppObj.Obj",1,0,"MyCppObj");
//MyCppObj.Obj:import的库的名字
//1:主版本号
//0:次版本号
//MyCppObj:QML中类的名字
  • 在qml文件中导入即可使用
javascript 复制代码
import QtQuick 2.15
import QtQuick.Window 2.15
import MyCppObj 1.0
Window {
    width: 640
    height: 480
    visible: true
    MyCppObj
    {
        id:myObj
        onIValueChanged: {}
        onSstringChanged: {}
    }
    Component.onCompleted:
    {
        console.log(myObj.iValue,myObj.sstring)
        myObj.func()
    }
}
QML端信号绑定到C++端(在qml端进行连接)

在以上内容的基础上即完成c++类的注册之后

  • 声明槽函数:
cpp 复制代码
public slots:
    void cppSlot(int i,QString s)
    {
    qDebug()<<__FUNCTION__<<i<<s;
	}
  • 在QML中进行连接
javascript 复制代码
Window {
    id:window
    width: 640
    height: 480
    visible: true
    signal qmlSignal(int i,string s)
    MyCppObj
    {
        id:myObj
        onIValueChanged: {}
        onSstringChanged: {}
    }

    Button{
        onClicked:
        {
            qmlSignal(10,"666")
        }
    }
    Connections
    {
        target: window
        function onQmlSignal(i,s)
        {
            myObj.cppSlot(i,s);
        }
    }
}
  • 另一种连接方法
javascript 复制代码
Component.onCompleted:
    {
        qmlSignal.connect(myObj.cppSlot)
    }
在C++端进行连接
cpp 复制代码
engine.load(url);
auto list = engine.rootObjects();//在engine.load之后
auto window = list.first();
MyCppObj *myObj = new MyCppObj();
    QObject::connect(window,SIGNAL(qmlSignal(int,QString)),myObj,SLOT(cppSlot(int,QString)));
C++端信号绑定到QML端
  • 在qml端进行绑定

    Button{
    onClicked:
    {
    myObj.cppSignal(10,"6")
    }
    }
    function qmlSlot(i,s)
    {
    console.log("qml",i,s)
    }
    Connections
    {
    target: myObj
    function onCppSignal(i,s)
    {
    qmlSlot(i,s);
    }
    }

  • 在c++端进行连接

注意收发双方参数都应该是QVariant类型

QObject::connect(myObj,SIGNAL(cppSignal(QVariant,QVariant)),window,SLOT(qmlSlot(QVariant,QVariant)));
注册单例类

当我们使用qmlRegisterType时,要通过创建对象来定义我们自定义的obj,对象存在于qml端,当我们需要类存在于全局时可使用qmlRegisterSingletonInstance

cpp 复制代码
 MyCppObj *myObj = new MyCppObj();
    qmlRegisterSingletonInstance("MyCppObjSingle",1,0,"MyCppObj",myObj);
C++端调用QML端函数
  • 获取qml对象
cpp 复制代码
auto list = engine.rootObjects();
    auto window = list.first();
  • 准备返回值和参数
cpp 复制代码
 QVariant res;
 QVariant arg_1 = 123;
 QVariant arg_2 = "ffffff";
  • 通过QMetaObject::invokeMethod调用
cpp 复制代码
QMetaObject::invokeMethod(window,//获取到的qml对象
						 "qmlFunc",//需要调用的函数名
						  Q_RETURN_ARG(QVariant,res),//准备好的返回值和参数
						  Q_ARG(QVariant,arg_1),
						  Q_ARG(QVariant,arg_2));
相关推荐
thesky1234562 分钟前
活着就好20241226
学习·算法
1101 110117 分钟前
STM32-笔记8-433M点灯
笔记
1101 110118 分钟前
STM32-笔记14-排队控制系统
笔记·stm32·嵌入式硬件
捕鲸叉21 分钟前
C++软件设计模式之代理(Proxy)模式
c++·设计模式
林浔090623 分钟前
QT信号槽
开发语言·qt
远离UE41 小时前
UE5 渲染管线 学习笔记
笔记·学习·ue5
code monkey.1 小时前
【排序算法】—— 计数排序
c++·算法·排序算法
云青山水林1 小时前
2024.12.21 周六
c++·算法·贪心算法
kiiila1 小时前
【Qt】编辑框/按钮控件---实现HelloWorld
开发语言·qt
Moweiii1 小时前
SDL3 GPU编程探索
c++·游戏引擎·图形渲染·sdl·vulkan