【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));
相关推荐
鱼子星_9 小时前
《算 · 法》题目解析篇(1):最近公共祖先问题,线段树,最长回文子序列
c++·算法·动态规划·递归
编程圈子9 小时前
电机驱动开发学习21. R3_2 双相扇区电流采样与第三相重构
驱动开发·学习·重构
chnyi6_ya10 小时前
论文阅读笔记 | The Script is All You Need: 对话到电影级视频生成的 Agentic 框架
论文阅读·笔记
Richard.Wong10 小时前
qt生成dll供C#调用
开发语言·qt
听雨入夜10 小时前
CMake构建学习笔记-libxml库的构建
笔记·学习
iiiiii1110 小时前
【论文阅读笔记】Reparameterization Proximal Policy Optimization (RPO):将PPO的稳定性引入可微分强化学习
论文阅读·人工智能·笔记·深度学习·机器学习·机器人·具身智能
计算机内卷的N天11 小时前
CMake与Visual Studio的使用
c++·ide·visual studio
不在逃避q11 小时前
一步一步学习使用LiveBindings()TListView进阶使用(),打造天气预报程序
服务器·数据库·学习
汉克老师11 小时前
GESP2026年3月认证C++七级( 第三部分编程题(1、物流网络))精讲
c++·最短路·gesp7级
鱼子星_11 小时前
【C++】深入剖析list:list及其双向迭代器实现
开发语言·数据结构·c++·笔记·stl·list