【Qt- C++ & Qml 交互】

发布时间:2024年01月06日

■ 注册 C++ 对象到 QML,在 QML 中访问 C++对象;

通过将c++类对象注册到元对象中,这样可以在qml中使用该对象的方法。

■ . C++ 对象注册到元对象系统

QQmlApplicationEngine::rootContext()->setContextProperty()

■ . Q_INVOKABLE 宏定义是将C++ 的 函数(方法)声明为元对象系统可调用的函数

Q_INVOKABLE
Q_INVOKABLE 是个宏定义,这个宏将 函数 声明为元对象系统可调用的函数

  • Q_INVOKABLE 是个宏定义
  • 这个宏定义 针对的是 函数, 不是变量
  • 经过Q_INVOKABLE 声明过得函数 可以被元对象系统调用
  • QtQuick 也在元对象系统内,所以在 QML 中也可以访问这个被声明了的函数

■ .演示步骤

  1. 新建qml工程,里面只有一个main.cpp 与一个默认的 main.qml
  2. 创建一个C++ 的类 MyQmlClass 来与 QML 进行交互(重点关注 函数 Q_INVOKABLE宏
  3. 将 C++ 的对象,注册到 QML中去 QQmlApplicationEngine::rootContext()->setContextProperty()
  4. 做完了这两步,我们就做了 C++ 的工作,在 QML 中 就可以 直接拿到对象 myQmlImp 来调用使用 Q_INVOKABLE 定义的方法了。
  5. 改造 QML (定义一个“获取”的 Button 与 显示获取值得 Label, 点击 Button 就会获取 C++ 中的 m_value 值, 在 Lable 上进行展示。)

MyQmlClass.h

#ifndef MYQMLCLASS_H
#define MYQMLCLASS_H
 
#include <QObject> 
class MyQmlClass : public QObject
{
    Q_OBJECT
public:
    explicit MyQmlClass(QObject *parent = nullptr);
 
    Q_INVOKABLE void setValue(int value);    //这个宏将 函数 声明为元对象系统可调用的函数
    Q_INVOKABLE int getValue();   //这个宏将 函数 声明为元对象系统可调用的函数
 
signals:
 
private:
    int m_Value;
};
 
#endif // MYQMLCLASS_H

MyQmlClass.cpp

#include "MyQmlClass.h"
 
MyQmlClass::MyQmlClass(QObject *parent) : QObject(parent)
{
 
}
 
void MyQmlClass::setValue(int value)
{
    m_Value = value;
}
 
int MyQmlClass::getValue()
{
    return m_Value;
}

打开 main.cpp ,通过 QML 引擎 QQmlApplicationEngine 进行注册。

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
 
#include "MyQmlClass.h"
 
int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); 
    QGuiApplication app(argc, argv); 
    QQmlApplicationEngine engine;
 
    ///
    //声明 对象  首先定义了一个C++ 的对象 myQmlImp ,
    MyQmlClass myQmlImp; 
    //将对象进行注册到QML中
    //key :自定义字符串,为了好记,我们这里叫做对象的名字 "myQmlImp"
	//value : 对象引用,对象指针,这里就是&myQmlImp
    engine.rootContext()->setContextProperty("myQmlImp", &myQmlImp);
 
    /// 
    const QUrl url(QStringLiteral("qrc:/main.qml"));
    QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
                     &app, [url](QObject *obj, const QUrl &objUrl) {
        if (!obj && url == objUrl)
            QCoreApplication::exit(-1);
    }, Qt::QueuedConnection);
    engine.load(url);
 
    return app.exec();
}

main.qml我们的思路很简单,就是 QML 中来调用上面 C++ 暴露出来的读写函数。所以我们在QML 中定义一个 “获取” Button ,点击它我们就来调用C++中的 getValue() 函数,然后我们需要一个Label 将获取的 C++ 的值进行展示

import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Controls 2.3
 
Window {
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")
 
    Label{                         //Label用于显示获取C++的值
        id: label                  //显示控件,唯一标识ID:label
        text: ""                   //初始化内容清空
 
        anchors.bottom: getBtn.top //显示控件的下方放到btn的上方
        anchors.left: getBtn.left  //显示控件的左方与btn的左侧对齐
    }
 
    Button{                       //Button 用于获取值
        id: getBtn                 //按钮控件,唯一标识ID:getBtn
        text: "获取"                //按钮显示文字
        width: 120                 //按钮宽度
        height: 40                 //按钮高度
 
        anchors.centerIn: parent   //按钮放到窗口中心
 
        onClicked: {               //点击按钮事件;
            label.text = myQmlImp.getValue()
        }
    }
}

在这里插入图片描述
到这里,我们就在 QML 中获取了 C++ 代码中的值。可能到这里还有老师感觉不太真实,那么我们就继续进行验证,我们的思路是这样的:

  1. 我们增加一个 TextFiled 用于输入我们想给 。
  2. 再增加一个 “设置” 按钮,将 1中输入的值,给C++ 中的 m_Value 设值。
  3. 然后我们再点击刚才的 “获取” 按钮,将 C++ 中的 m_Value 值读取并显示出来。
    这时候我们需要对原来的QML进行改造,新增加一个输入框TextField ,进行数值输入; 还需要新增加一个“设置” 按钮,点击按钮将值赋给 C++ 中的 m_Value

main.qml

import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Controls 2.3
 
Window {
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World") 
 
    Label{                         //Label用于显示获取C++的值
        id: label                  //显示控件,唯一标识ID:label
        text: ""                   //初始化内容清空
 
        anchors.bottom: getBtn.top //显示控件的下方放到btn的上方
        anchors.left: getBtn.left  //显示控件的左方与btn的左侧对齐
    }
 
    Button{                       //Button 用于获取值
        id: getBtn                 //按钮控件,唯一标识ID:getBtn
        text: "获取"                //按钮显示文字
        width: 120                 //按钮宽度
        height: 40                 //按钮高度
 
        anchors.centerIn: parent   //按钮放到窗口中心
 
        onClicked: {               //点击按钮事件;
            label.text = myQmlImp.getValue()
        }
    }
 
    TextField{                      //文字输入控件
        id: textField               //唯一ID
        width: getBtn.width         //也可以直接设置成120
        height: getBtn.height       //也可以直接设置成40
 
        anchors.top: getBtn.bottom  //放到“获取”按钮下方10个像素
        anchors.topMargin: 10
        anchors.left: getBtn.left   //与“获取”按钮左对齐
    }
 
    Button{
        id: setBtn
        text: "设置"
        width: textField.width      //可以设置成getBtn.width或者120
        height: textField.height    //可以设置成getBtn.height或者40
 
        anchors.top: textField.bottom
        anchors.left: textField.left
 
        onClicked: {
            var value = textField.text
            myQmlImp.setValue(value)
        } 
    }  
}

在这里插入图片描述

■ QML 暴露对象给 C++ 进行交互

■ C++ 创建 QML 对象并进行交互

■ C++ 对象与 QML 通过信号槽进行交互

文章来源:https://blog.csdn.net/sinat_23896491/article/details/135423953
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。