C++与QML的数据交互

C++与QML的数据交互

  • 1、使用结构体
  • 2、使用json
  • 2、使用QVariantList、QVarianMap
  • 3、使用QObject类和Q_PROPERTY双向绑定

1、使用结构体

在C++中声明并注册一个结构体

struct Data {
    Q_GADGET
    Q_PROPERTY(int32_t can_id MEMBER can_id)
    Q_PROPERTY(int32_t heatlid_kp MEMBER heatlid_kp)
    Q_PROPERTY(int32_t heatlid_ki MEMBER heatlid_ki)
    Q_PROPERTY(int32_t heatlid_kd MEMBER heatlid_kd)
    Q_PROPERTY(int32_t block_kp MEMBER block_kp)
    Q_PROPERTY(int32_t block_ki MEMBER block_ki)
    Q_PROPERTY(int32_t block_kd MEMBER block_kd)
    Q_PROPERTY(int32_t lid_move_distance MEMBER lid_move_distance)
    Q_PROPERTY(int32_t baundrate MEMBER baundrate)
    Q_PROPERTY(int32_t block1 MEMBER block1)
    Q_PROPERTY(int32_t block2 MEMBER block2)
    Q_PROPERTY(int32_t block3 MEMBER block3)
    Q_PROPERTY(int32_t heatLid MEMBER heatLid)
    Q_PROPERTY(int32_t radiator MEMBER radiator)
    Q_PROPERTY(int32_t k MEMBER k)
    Q_PROPERTY(int32_t b MEMBER b)

public:
    int32_t can_id = -1;
    int32_t heatlid_kp = -1;
    int32_t heatlid_ki = -1;
    int32_t heatlid_kd = -1;
    int32_t block_kp = -1;
    int32_t block_ki = -1;
    int32_t block_kd = -1;
    int32_t lid_move_distance = -1;
    int32_t baundrate = -1;
    int32_t block1 = -1;
    int32_t block2 = -1;
    int32_t block3 = -1;
    int32_t heatLid = -1;
    int32_t radiator = -1;
    int32_t k = -1;
    int32_t b = -1;
};

//注册为元类型
Q_DECLARE_METATYPE(Data)
qRegisterMetaType<Data>("Data");

然后发送信号到QML中

void DataHandler::onSigSendParams(const QString &deviceName, const Data &data)
{
    Q_EMIT sigSendParams(deviceName, data);
}

在QML接收,直接通过data.can_id这样的形式去访问结构体中的元素

Connections {
	target: DataHandler
    function onSigSendParams(name, data) {
    	if(name !== deviceName) {
        	return
        }
        console.log("name: ", name, ", data.can_id: ", data.can_id)
    }
}

2、使用json

这里没什么好说的,在C++中组合好json后,通过信号发送到qml中,qml中是可以解析json的。
例如:

QVariantList vec_res;
vec_res.append(valueTemperature1 / 1000);
vec_res.append(valueTemperature2 / 1000);
vec_res.append(valueTemperature4 / 1000);
vec_res.append(valueTemperature3 / 1000);
vec_res.append(valueTemperature5 / 1000);

Q_EMIT sigManager->sigSendTemperature(deviceName, vec_res);
Connections {
        target: DataHandler

        function onSigSendTemperature(device, temperatureList) {
            if(!showLine || device !== deviceName) {
                return
            } else {
                x_Axis += 2
                if(x_Axis > xAxis.max) {
                    xAxis.max = x_Axis
                }

                root.block1Line.append(x_Axis, temperatureList[0]);
                root.block2Line.append(x_Axis, temperatureList[1]);
                root.block3Line.append(x_Axis, temperatureList[2]);
                root.heatLidLine.append(x_Axis, temperatureList[3]);
            }
        }
    }

2、使用QVariantList、QVarianMap

这两个也没什么好说的,在C++中直接发送信号,在qml中接收,例如:

QVariantList vec_res;
    vec_res.append(valueTemperature1 / 1000);
    vec_res.append(valueTemperature2 / 1000);
    vec_res.append(valueTemperature4 / 1000);
    vec_res.append(valueTemperature3 / 1000);
    vec_res.append(valueTemperature5 / 1000);

    Q_EMIT sigManager->sigSendTemperature(deviceName, vec_res);
Connections {
        target: DataHandler

        function onSigSendTemperature(device, temperatureList) {
            if(!showLine || device !== deviceName) {
                return
            } else {
                x_Axis += 2
                if(x_Axis > xAxis.max) {
                    xAxis.max = x_Axis
                }

                root.block1Line.append(x_Axis, temperatureList[0]);
                root.block2Line.append(x_Axis, temperatureList[1]);
                root.block3Line.append(x_Axis, temperatureList[2]);
                root.heatLidLine.append(x_Axis, temperatureList[3]);
            }
        }
    }

3、使用QObject类和Q_PROPERTY双向绑定

通过Q_PROPERTY属性,可以轻松地在QML中读取和修改数据,并将其更新到C++中,先创建一个类

#include 

class SensorData : public QObject {
    Q_OBJECT
    Q_PROPERTY(int temperature READ temperature WRITE setTemperature NOTIFY temperatureChanged)
    Q_PROPERTY(int time READ time WRITE setTime NOTIFY timeChanged)
    Q_PROPERTY(int compensation READ compensation WRITE setCompensation NOTIFY compensationChanged)

public:
    explicit SensorData(QObject *parent = nullptr) : QObject(parent), m_temperature(0), m_time(0), m_compensation(0) {}

    int temperature() const { return m_temperature; }
    void setTemperature(int temperature) {
        if (m_temperature != temperature) {
            m_temperature = temperature;
            emit temperatureChanged();
        }
    }

    int time() const { return m_time; }
    void setTime(int time) {
        if (m_time != time) {
            m_time = time;
            emit timeChanged();
        }
    }

    int compensation() const { return m_compensation; }
    void setCompensation(int compensation) {
        if (m_compensation != compensation) {
            m_compensation = compensation;
            emit compensationChanged();
        }
    }

signals:
    void temperatureChanged();
    void timeChanged();
    void compensationChanged();

private:
    int m_temperature;
    int m_time;
    int m_compensation;
};

传递给qml

#include 
#include 
#include 
#include "sensordata.h"  // 包含上面定义的 SensorData 类

int main(int argc, char *argv[])
{
    QGuiApplication app(argc, argv);
    QQmlApplicationEngine engine;

    // 实例化 SensorData 对象
    SensorData sensorData;
    sensorData.setTemperature(25);  // 设置初始值
    sensorData.setTime(1620);       // 时间
    sensorData.setCompensation(15); // 补偿值

    // 将 SensorData 对象传递给 QML
    engine.rootContext()->setContextProperty("sensorData", &sensorData);

    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
    return app.exec();
}

import QtQuick 2.15
import QtQuick.Controls 2.15

ApplicationWindow {
    visible: true
    width: 640
    height: 480

    Column {
        spacing: 20
        anchors.centerIn: parent

        Text {
            text: "Temperature: " + sensorData.temperature + " °C"
        }

        Text {
            text: "Time: " + sensorData.time
        }

        Text {
            text: "Compensation: " + sensorData.compensation
        }

        Button {
            text: "更新温度"
            onClicked: {
                sensorData.temperature = 30;  // 更新温度
            }
        }
    }
}

你可能感兴趣的:(c++,交互,qt)