Qt/C++ 如何通过 QML 和 C++ 实现实时数据反馈(附代码下载链接)

在 Qt 应用程序开发中,QML 和 C++ 的结合可以为我们提供强大的数据交互和界面构建能力。QML 主要负责用户界面的展示,而 C++ 则处理业务逻辑和数据。通过 C++ 的信号与槽机制,QML 可以接收来自 C++ 的数据并实时更新界面。

文章源码下载

通过网盘分享的文件:QML实时监控带参信号
链接: https://pan.baidu.com/s/1BdhzcYDltGWw95OJtoTY6g?pwd=jkcf 提取码: jkcf

1. C++ 中的信号和定时器

在 Qt 中,信号与槽机制是 C++ 类与 QML 交互的核心。我们可以在 C++ 类中定义信号,并通过定时器周期性地发送数据。在本例中,我们将创建一个 C++ 类 MyClass,它包含一个 QTimer 定时器,每秒钟更新一次 JSON 数据,并通过信号将数据发送给 QML。

定义信号与槽

首先,我们在 C++ 类 MyClass 中定义一个信号 messageChanged,它携带一个 QJsonObject 作为参数。QJsonObject 用来传递每次更新的数据。通过定时器,每秒触发一次 updateMessage 槽函数,生成新的 JSON 数据并发射信号。

#ifndef MYCLASS_H
#define MYCLASS_H

#include <QObject>
#include <QTimer>
#include <QJsonObject>
#include <QJsonDocument>
#include <QDateTime>

class MyClass : public QObject
{
    Q_OBJECT

public:
    explicit MyClass(QObject *parent = nullptr);
    ~MyClass();

signals:
    // 定义一个带参数的信号,参数为 JSON 对象
    void messageChanged(const QJsonObject &message);

public slots:
    // 一个槽,用于启动定时器
    void startTimer();

private slots:
    // 定时器槽,每次触发时更新 JSON 数据并发射信号
    void updateMessage();

private:
    QTimer *timer;  // 定时器
};

#endif // MYCLASS_H

MyClass 类中,我们使用 QTimer 来设置一个定时器,每秒更新一次数据,并通过 messageChanged 信号将数据发送给 QML。

定时器触发更新数据

在实现文件 MyClass.cpp 中,我们连接定时器的 timeout 信号到 updateMessage 槽函数。每次触发时,生成一个新的 JSON 对象,包含当前时间和消息内容,并通过信号发射到 QML。

#include "MyClass.h"
#include <QDebug>

MyClass::MyClass(QObject *parent) : QObject(parent), timer(new QTimer(this))
{
    // 设置定时器,每隔 1 秒触发一次
    connect(timer, &QTimer::timeout, this, &MyClass::updateMessage);
}

MyClass::~MyClass()
{
    // 确保定时器被销毁前停止
    if (timer->isActive()) {
        timer->stop();
    }
}

void MyClass::startTimer()
{
    // 启动定时器
    if (!timer->isActive()) {
        timer->start(1000);  // 1000 毫秒 = 1 秒
    }
}

void MyClass::updateMessage()
{
    // 创建一个 JSON 对象,每次更新时设置不同的值
    QJsonObject jsonObject;
    jsonObject["timestamp"] = QDateTime::currentDateTime().toString();
    jsonObject["message"] = QString("Updated at: %1").arg(QDateTime::currentDateTime().toString());

    // 发射带有 JSON 格式的信号
    emit messageChanged(jsonObject);
}

在此代码中,定时器每秒触发一次,updateMessage 函数会创建一个新的 QJsonObject,并将当前的时间戳和消息发送给 QML。通过 emit messageChanged(jsonObject);,信号携带 JSON 数据发射出去。


2. QML 中的信号监听

在 QML 中,我们可以通过 Component.onCompleted 来确保 QML 加载完成后立即连接到 C++ 类中的信号。通过连接信号,QML 可以实时接收到来自 C++ 的数据,并进行相应的处理和展示。

监听 C++ 信号

在 QML 中,我们通过 myClass.messageChanged.connect(onMessageChanged) 来连接 C++ 类中的信号。一旦 C++ 发射信号,QML 中的 onMessageChanged 函数就会被触发,接受 JSON 数据,并将其展示出来。

import QtQuick 2.15
import QtQuick.Controls 2.15

ApplicationWindow {
    visible: true
    width: 640
    height: 480

    // 在 QML 中监听 C++ 类的信号
    Component.onCompleted: {
        myClass.messageChanged.connect(onMessageChanged);
    }

    // 处理信号的槽
    function onMessageChanged(message) {
        // 输出 JSON 格式的消息
        console.log("Received JSON message:", message);
        console.log("Timestamp:", message.timestamp);
        console.log("Message:", message.message);
    }

    // 按钮用于触发 C++ 类中的方法
    Button {
        text: "Start Timer"
        anchors.centerIn: parent
        onClicked: {
            // 启动定时器
            myClass.startTimer();
        }
    }
}

在 QML 代码中,我们使用 messageChanged.connect(onMessageChanged) 来连接信号。当信号触发时,onMessageChanged 函数会接收到 JSON 数据,并通过 console.log 打印出来。我们还为界面添加了一个按钮,点击按钮后将启动 C++ 类中的定时器。


3. 将 C++ 与 QML 结合

为了将 C++ 类与 QML 结合,我们需要在 main.cpp 中进行设置。通过 QQmlApplicationEngine 加载 QML 文件,并将 C++ 对象暴露给 QML。通过 setContextProperty 方法,将 C++ 类中的对象传递给 QML,确保 QML 能够访问这些对象的信号和槽。

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include "MyClass.h"

int main(int argc, char *argv[])
{
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
#endif
    QGuiApplication app(argc, argv);

    QQmlApplicationEngine engine;

    // 创建 C++ 对象
    MyClass myClass;

    // 将 C++ 对象暴露到 QML
    engine.rootContext()->setContextProperty("myClass", &myClass);

    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.cpp 中,我们创建了 MyClass 对象,并通过 rootContext()->setContextProperty("myClass", &myClass) 将其暴露给 QML。这样,QML 中就可以通过 myClass 访问 C++ 类中的信号和方法。


4. 总结

通过 C++ 和 QML 之间的信号与槽机制,我们能够实现实时的数据反馈。在本例中,我们使用 C++ 中的定时器定期生成 JSON 数据,并通过信号传递给 QML。QML 中通过连接信号,接收数据并更新界面。利用这种方法,我们可以在应用程序中实现动态更新和实时数据处理,增强用户体验。

通过这种方式,C++ 负责复杂的逻辑和数据处理,而 QML 则专注于界面的呈现和用户交互。这种设计模式使得应用程序的开发更加灵活和高效。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

极客晨风

感谢支持

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值