简单 MQTT 客户端示例#

简单 MQTT 客户端示例演示了如何创建一个最小客户端应用程序。

要使用该应用程序,您首先指定一个代理,例如 test.mosquitto.orgbroker.hivemq.com 以及端口号 1883,并将其连接到。然后您可以订阅一个主题并发送消息,您也将接收这些消息。

注意

端口号 1883 未加密,因此仅适用于开发和测试目的。在生产环境中,始终使用加密连接。

Simple MQTT Client Example Screenshot

下载 示例

# Copyright (C) 2020 The Qt Company Ltd.
# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause

import sys

from PySide6.QtWidgets import QApplication

from mainwindow import MainWindow

if __name__ == "__main__":
    app = QApplication(sys.argv)
    w = MainWindow()
    w.show()

    sys.exit(app.exec())
# Copyright (C) 2020 The Qt Company Ltd.
# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause

from PySide6.QtCore import QByteArray, QDateTime, Slot
from PySide6.QtGui import QKeySequence
from PySide6.QtMqtt import QMqttClient, QMqttTopicName
from PySide6.QtWidgets import QMainWindow, QMessageBox

from ui_mainwindow import Ui_MainWindow as ui


class MainWindow(QMainWindow):
    def __init__(self, parent=None):
        QMainWindow.__init__(self, parent)
        self._ui = ui()
        self._ui.setupUi(self)
        self._ui.actionQuit.setShortcut(QKeySequence.StandardKey.Quit)
        self._ui.actionQuit.triggered.connect(self.close)

        self._client = QMqttClient(self)
        self._client.setHostname(self._ui.lineEditHost.text())
        self._client.setPort(self._ui.spinBoxPort.value())

        self._client.stateChanged.connect(self.updateLogStateChange)
        self._client.disconnected.connect(self.brokerDisconnected)
        self._client.messageReceived.connect(self.on_messageReceived)
        self._client.pingResponseReceived.connect(self.on_pingResponseReceived)

        self._ui.lineEditHost.textChanged.connect(self._client.setHostname)
        self._ui.spinBoxPort.valueChanged[int].connect(self.setClientPort)
        self.updateLogStateChange()

    @Slot()
    def on_pingResponseReceived(self):
        current_date = QDateTime.currentDateTime().toString()
        self._ui.editLog.insertPlainText(current_date + "PingResponse\n")

    @Slot(QByteArray, QMqttTopicName)
    def on_messageReceived(self, message, topic):
        current_date = QDateTime.currentDateTime().toString()
        data = message.data().decode("utf-8")
        content = f"{current_date} Received Topic: {topic.name()} Message: {data}\n"
        self._ui.editLog.insertPlainText(content)

    @Slot(int)
    def setClientPort(self, p):
        self._client.setPort(p)

    @Slot()
    def on_buttonConnect_clicked(self):
        if self._client.state() == QMqttClient.Connected:
            self._ui.lineEditHost.setEnabled(True)
            self._ui.spinBoxPort.setEnabled(True)
            self._ui.buttonConnect.setText("Connect")
            self._client.disconnectFromHost()
        elif self._client.hostname():
            self._ui.lineEditHost.setEnabled(False)
            self._ui.spinBoxPort.setEnabled(False)
            self._ui.buttonConnect.setText("Disconnect")
            self._client.connectToHost()

    @Slot()
    def on_buttonQuit_clicked(self):
        qApp.quit()  # noqa: F821

    @Slot()
    def updateLogStateChange(self):
        current_date = QDateTime.currentDateTime().toString()
        content = f"{current_date}: State Change {self._client.state()}\n"
        self._ui.editLog.insertPlainText(content)

    @Slot()
    def brokerDisconnected(self):
        self._ui.lineEditHost.setEnabled(True)
        self._ui.spinBoxPort.setEnabled(True)
        self._ui.buttonConnect.setText("Connect")

    @Slot()
    def on_buttonPublish_clicked(self):
        topic = QMqttTopicName(self._ui.lineEditTopic.text())
        message = QByteArray(self._ui.lineEditMessage.text().encode("utf-8"))
        if self._client.publish(topic, message) == -1:
            QMessageBox.critical(self, "Error", "Could not publish message")

    @Slot()
    def on_buttonSubscribe_clicked(self):
        subscription = self._client.subscribe(self._ui.lineEditTopic.text())
        if not subscription:
            QMessageBox.critical(self, "Error",
                                 "Could not subscribe. Is there a valid connection?")
            return
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>MainWindow</class>
 <widget class="QMainWindow" name="MainWindow">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>1024</width>
    <height>768</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>MainWindow</string>
  </property>
  <widget class="QWidget" name="centralWidget">
   <layout class="QVBoxLayout" name="verticalLayout">
    <item>
     <layout class="QHBoxLayout" name="horizontalLayout">
      <item>
       <layout class="QFormLayout" name="formLayout">
        <item row="0" column="0">
         <widget class="QLabel" name="label">
          <property name="text">
           <string>Host:</string>
          </property>
         </widget>
        </item>
        <item row="0" column="1">
         <widget class="QLineEdit" name="lineEditHost">
          <property name="text">
           <string/>
          </property>
         </widget>
        </item>
        <item row="2" column="0">
         <widget class="QLabel" name="label_2">
          <property name="text">
           <string>Port:</string>
          </property>
         </widget>
        </item>
        <item row="2" column="1">
         <widget class="QSpinBox" name="spinBoxPort">
          <property name="maximum">
           <number>99999</number>
          </property>
          <property name="value">
           <number>1883</number>
          </property>
         </widget>
        </item>
       </layout>
      </item>
      <item>
       <widget class="QPushButton" name="buttonConnect">
        <property name="text">
         <string>Connect</string>
        </property>
       </widget>
      </item>
     </layout>
    </item>
    <item>
     <layout class="QGridLayout" name="gridLayout">
      <item row="1" column="1">
       <widget class="QLineEdit" name="lineEditMessage">
        <property name="text">
         <string>This is a test message</string>
        </property>
       </widget>
      </item>
      <item row="1" column="0">
       <widget class="QLabel" name="label_4">
        <property name="text">
         <string>Message:</string>
        </property>
       </widget>
      </item>
      <item row="0" column="2">
       <widget class="QPushButton" name="buttonSubscribe">
        <property name="text">
         <string>Subscribe</string>
        </property>
       </widget>
      </item>
      <item row="1" column="2">
       <widget class="QPushButton" name="buttonPublish">
        <property name="text">
         <string>Publish</string>
        </property>
       </widget>
      </item>
      <item row="0" column="1">
       <widget class="QLineEdit" name="lineEditTopic">
        <property name="text">
         <string>qtmqtt/topic1</string>
        </property>
       </widget>
      </item>
      <item row="0" column="0">
       <widget class="QLabel" name="label_3">
        <property name="text">
         <string>Topic:</string>
        </property>
       </widget>
      </item>
     </layout>
    </item>
    <item>
     <widget class="QGroupBox" name="groupBox">
      <property name="title">
       <string>Log Messages</string>
      </property>
      <layout class="QHBoxLayout" name="horizontalLayout_2">
       <item>
        <widget class="QPlainTextEdit" name="editLog"/>
       </item>
      </layout>
     </widget>
    </item>
    <item>
     <layout class="QHBoxLayout" name="horizontalLayout_3">
      <item>
       <spacer name="horizontalSpacer">
        <property name="orientation">
         <enum>Qt::Horizontal</enum>
        </property>
        <property name="sizeHint" stdset="0">
         <size>
          <width>40</width>
          <height>20</height>
         </size>
        </property>
       </spacer>
      </item>
      <item>
       <widget class="QPushButton" name="buttonQuit">
        <property name="text">
         <string>Quit</string>
        </property>
       </widget>
      </item>
     </layout>
    </item>
   </layout>
  </widget>
  <widget class="QMenuBar" name="menuBar">
   <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
     <width>1024</width>
     <height>20</height>
    </rect>
   </property>
   <widget class="QMenu" name="menuFile">
    <property name="title">
     <string>File</string>
    </property>
    <addaction name="actionQuit"/>
   </widget>
   <addaction name="menuFile"/>
  </widget>
  <widget class="QToolBar" name="mainToolBar">
   <attribute name="toolBarArea">
    <enum>TopToolBarArea</enum>
   </attribute>
   <attribute name="toolBarBreak">
    <bool>false</bool>
   </attribute>
  </widget>
  <widget class="QStatusBar" name="statusBar"/>
  <action name="actionQuit">
   <property name="text">
    <string>Quit</string>
   </property>
  </action>
 </widget>
 <layoutdefault spacing="6" margin="11"/>
 <resources/>
 <connections/>
</ui>