Qt中简单使用MQTT(一)

Qt中简单使用MQTT(一)

MQTT简介可以看下这篇文章:

MQTT简介

一、MQTT库配置

1.下载MQTT源码

我们的QtCreator中是不带MQTT模块的,需要我们自己去下载。使用git工具下载如下:

由于我用的是 Qt6.6.0 版本,下载是需要严格对应 6.6.0版本。

复制代码
git clone https://github.com/qt/qtmqtt.git
cd qtmqtt
git checkout 6.6.0

下载完后,文件如图:

2.编译MQTT源码

1.步骤:使用QtCreator打开上述的CMakeList.txt文件,并且选择构建套件。如图:

我的构建套件中只能选择MingGW 64bit和MSVC 2019 64Bit,我这里选择生成的是MingGW 64位。

2.选择release版本生成.a和.dll文件

如下所示:

3.将库复制到QtCreator配置中

需要复制的文件清单:

源文件(你 build 目录里的) 目标位置(Qt 6.6.0 目录)
build\...\include\ 下的所有头文件 E:\QtCreator\QtCreator\6.6.0\mingw_64\include\QtMqtt\
build\...\lib\libQt6Mqtt.a E:\QtCreator\QtCreator\6.6.0\mingw_64\lib\
build\...\lib\Qt6Mqtt.prl E:\QtCreator\QtCreator\6.6.0\mingw_64\lib\
build\...\lib\cmake\Qt6Mqtt\ 下所有文件 E:\QtCreator\QtCreator\6.6.0\mingw_64\lib\cmake\Qt6Mqtt\
build\...\bin\Qt6Mqtt.dll E:\QtCreator\QtCreator\6.6.0\mingw_64\bin\

头文件在源码目录 qtmqtt\src\mqtt\ 下,.h 文件需要全部复制过去。

如下图,是我已经复制完成后的目录:

二、在项目中使用MQTT库

1.加载MQTT库

创建一个QWidget 的MQTTTest项目,并且在CMakeList.txt文件中加载MQTT库,如下图:

2.项目测试代码如下:

MainWindow.h

c++ 复制代码
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QMqttClient>

QT_BEGIN_NAMESPACE
class QLineEdit;
class QPushButton;
class QTextEdit;
class QVBoxLayout;
QT_END_NAMESPACE

QT_BEGIN_NAMESPACE
namespace Ui {
class MainWindow;
}
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private:
    Ui::MainWindow *ui;

private slots:
    void onConnectClicked();
    void onSubscribeClicked();
    void onPublishClicked();
    void onConnected();
    void onMessageReceived(const QByteArray &message, const QMqttTopicName &topic);
    void onDisconnected();
    void onErrorChanged(QMqttClient::ClientError error);

private:
    QMqttClient *m_client;

    // UI
    QLineEdit *m_hostEdit;
    QLineEdit *m_portEdit;
    QLineEdit *m_topicEdit;
    QLineEdit *m_msgEdit;
    QPushButton *m_connectBtn;
    QPushButton *m_subBtn;
    QPushButton *m_pubBtn;
    QTextEdit *m_logEdit;
};
#endif // MAINWINDOW_H

MainWindow.cpp

C++ 复制代码
#include "mainwindow.h"
#include <QLineEdit>
#include <QPushButton>
#include <QTextEdit>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QWidget>
#include <QDebug>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , m_client(new QMqttClient(this))
{
    // 中心窗口
    auto *central = new QWidget(this);
    auto *mainLayout = new QVBoxLayout(central);

    // 连接区域
    auto *connLayout = new QHBoxLayout();
    m_hostEdit = new QLineEdit("broker.hivemq.com", this);
    m_portEdit = new QLineEdit("1883", this);
    m_connectBtn = new QPushButton("连接", this);
    connLayout->addWidget(m_hostEdit);
    connLayout->addWidget(m_portEdit);
    connLayout->addWidget(m_connectBtn);

    // 订阅区域
    auto *subLayout = new QHBoxLayout();
    m_topicEdit = new QLineEdit("test/topic", this);
    m_subBtn = new QPushButton("订阅", this);
    subLayout->addWidget(m_topicEdit);
    subLayout->addWidget(m_subBtn);

    // 发布区域
    auto *pubLayout = new QHBoxLayout();
    m_msgEdit = new QLineEdit("Hello MQTT", this);
    m_pubBtn = new QPushButton("发布", this);
    pubLayout->addWidget(m_msgEdit);
    pubLayout->addWidget(m_pubBtn);

    // 日志显示
    m_logEdit = new QTextEdit(this);
    m_logEdit->setReadOnly(true);

    mainLayout->addLayout(connLayout);
    mainLayout->addLayout(subLayout);
    mainLayout->addLayout(pubLayout);
    mainLayout->addWidget(m_logEdit);

    setCentralWidget(central);
    setWindowTitle("Qt MQTT Demo");
    resize(500, 400);

    // 信号连接
    connect(m_connectBtn, &QPushButton::clicked, this, &MainWindow::onConnectClicked);
    connect(m_subBtn, &QPushButton::clicked, this, &MainWindow::onSubscribeClicked);
    connect(m_pubBtn, &QPushButton::clicked, this, &MainWindow::onPublishClicked);

    connect(m_client, &QMqttClient::connected, this, &MainWindow::onConnected);
    connect(m_client, &QMqttClient::messageReceived, this, &MainWindow::onMessageReceived);
    connect(m_client, &QMqttClient::disconnected, this, &MainWindow::onDisconnected);
    connect(m_client, &QMqttClient::errorChanged, this, &MainWindow::onErrorChanged);
}

MainWindow::~MainWindow() = default;

void MainWindow::onConnectClicked() {
    m_client->setHostname(m_hostEdit->text());
    m_client->setPort(m_portEdit->text().toInt());
    m_client->connectToHost();
    m_logEdit->append("正在连接...");
}

void MainWindow::onSubscribeClicked() {
    auto sub = m_client->subscribe(m_topicEdit->text());
    if (sub) {
        m_logEdit->append("已订阅: " + m_topicEdit->text());
    } else {
        m_logEdit->append("订阅失败,请检查是否已连接");
    }
}

void MainWindow::onPublishClicked() {
    auto result = m_client->publish(m_topicEdit->text(), m_msgEdit->text().toUtf8());
    if (result == -1) {
        m_logEdit->append("发布失败");
    } else {
        m_logEdit->append("已发送: " + m_msgEdit->text());
    }
}

void MainWindow::onConnected() {
    m_logEdit->append("✅ MQTT 连接成功!");
    m_connectBtn->setText("已连接");
    m_connectBtn->setEnabled(false);
}

void MainWindow::onMessageReceived(const QByteArray &message, const QMqttTopicName &topic) {
    m_logEdit->append("📩 [" + topic.name() + "] " + QString(message));
}

void MainWindow::onDisconnected() {
    m_logEdit->append("❌ 连接断开");
    m_connectBtn->setText("连接");
    m_connectBtn->setEnabled(true);
}

void MainWindow::onErrorChanged(QMqttClient::ClientError error) {
    m_logEdit->append("⚠️ 错误: " + QString::number(error));
}

项目运行效果:

好了,关于MOTT的使用就介绍到这里了。