Simple MQTT Client Example

The Simple MQTT Client example demonstrates how to create a minimal client application.

To use the application, you first specify a broker, such as test.mosquitto.org or broker.hivemq.com and the port number 1883, and connect to it. You can then subscribe to a topic and send a message, which you will also receive.

Note

Port number 1883 is not encrypted, and therefore it is suitable only for development and testing purposes. In production, always use encrypted connections.

Simple MQTT Client Example Screenshot

Download this example

# 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>