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


    QML与C++的交互

    在QML中访问c++对象
    • 首先创建一个类,这个类需继承自QObject,必须有Q_OBJECT宏,并加入QML_ELEMENT宏,并且私有成员具有Q_PROPERTY宏(可通过ALT+ENTER快速设置)
    #include 
    #include //注意 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文件中对对象进行注册
    //一定要通过创建对象来定义我们自定义的obj,对象存在于qml端
    qmlRegisterType<MyCppObj>("MyCppObj.Obj",1,0,"MyCppObj");
    //MyCppObj.Obj:import的库的名字
    //1:主版本号
    //0:次版本号
    //MyCppObj:QML中类的名字
    
    • 在qml文件中导入即可使用
    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++类的注册之后

    • 声明槽函数:
    public slots:
        void cppSlot(int i,QString s)
        {
        qDebug()<<__FUNCTION__<<i<<s;
    	}
    
    • 在QML中进行连接
    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);
            }
        }
    }
    
    • 另一种连接方法
    Component.onCompleted:
        {
            qmlSignal.connect(myObj.cppSlot)
        }
    
    在C++端进行连接
    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

     MyCppObj *myObj = new MyCppObj();
        qmlRegisterSingletonInstance("MyCppObjSingle",1,0,"MyCppObj",myObj);
    
    C++端调用QML端函数
    • 获取qml对象
    auto list = engine.rootObjects();
        auto window = list.first();
    
    • 准备返回值和参数
     QVariant res;
     QVariant arg_1 = 123;
     QVariant arg_2 = "ffffff";
    
    • 通过QMetaObject::invokeMethod调用
    QMetaObject::invokeMethod(window,//获取到的qml对象
    						 "qmlFunc",//需要调用的函数名
    						  Q_RETURN_ARG(QVariant,res),//准备好的返回值和参数
    						  Q_ARG(QVariant,arg_1),
    						  Q_ARG(QVariant,arg_2));
    
  • 相关阅读:
    Response对象-响应字符数据
    docker pull、docker load、docker run使用方法
    大开眼界,Jenkins 结合 SpringCloud+K8S,打通微服一条龙技术讲解
    最详细、最全面的【Java日志框架】介绍,建议收藏,包含JUL、log4j、logback、log4j2等所有主流框架
    Java端集成drools6.4.0.Final
    scala reduce、reduceLeft 、reduceRight 、fold、foldLeft 、foldRight
    第16篇ESP32 platformio_arduino框架 wifi联网_连接WiFi热点并连接tcp server收发数据进行通讯
    智能导诊(Intelligent Guidance,IG)源码
    Series (mathematics)
    (转)c 多张图片生成avi视频
  • 原文地址:https://blog.csdn.net/xia0414/article/details/140350191