【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));
相关推荐
牵牛老人几秒前
Qt技巧(三)编辑框嵌入按钮,系统位数判断,判断某对象是否属于某种类,控件取句柄,支持4K,巧用QEventLoop,QWidget的窗体样式
开发语言·qt
C1 分钟前
C++_map_set详解
c++·stl
Niu_brave5 分钟前
Python基础知识学习(2)
开发语言·python·学习
akbar&11 分钟前
计算机三级 - 数据库技术 - 第十三章 大规模数据库架构 笔记
数据库·笔记
大柏怎么被偷了28 分钟前
【C++算法】位运算
开发语言·c++·算法
sixteenyy29 分钟前
学习笔记(一)
笔记·学习
程序猿方梓燚29 分钟前
C/C++实现植物大战僵尸(PVZ)(打地鼠版)
c语言·开发语言·c++·算法·游戏
闻缺陷则喜何志丹30 分钟前
【C++前后缀分解 动态规划】2100. 适合野炊的日子|1702
c++·算法·动态规划·力扣·前后缀分解·日子·适合
冲,干,闯1 小时前
VScode相关问题与解决
c++·ide·vscode
计算机学姐1 小时前
基于python+django+vue的在线学习资源推送系统
开发语言·vue.js·python·学习·django·pip·web3.py