Finished implementing the connection options dialog.

Sun, 02 Sep 2018 18:29:35 +0200

author
Detlev Offenbach <detlev@die-offenbachs.de>
date
Sun, 02 Sep 2018 18:29:35 +0200
changeset 11
90d3ebed4cc0
parent 10
7e0e921dc7ea
child 12
e0175cb7c5d5

Finished implementing the connection options dialog.

MqttMonitor/MqttClient.py file | annotate | diff | comparison | revisions
MqttMonitor/MqttConnectionOptionsDialog.py file | annotate | diff | comparison | revisions
MqttMonitor/MqttConnectionOptionsDialog.ui file | annotate | diff | comparison | revisions
MqttMonitor/MqttMonitorWidget.py file | annotate | diff | comparison | revisions
MqttMonitor/MqttMonitorWidget.ui file | annotate | diff | comparison | revisions
diff -r 7e0e921dc7ea -r 90d3ebed4cc0 MqttMonitor/MqttClient.py
--- a/MqttMonitor/MqttClient.py	Sat Sep 01 20:18:11 2018 +0200
+++ b/MqttMonitor/MqttClient.py	Sun Sep 02 18:29:35 2018 +0200
@@ -63,6 +63,12 @@
             client_id=clientId, clean_session=cleanSession, userdata=None,
             protocol=mqtt.MQTTv311, transport="tcp")
         
+        self.__initCallbacks()
+
+    def __initCallbacks(self):
+        """
+        Private method to initialize the MQTT callback methods.
+        """
         self.__mqttClient.on_connect = \
             lambda client, userdata, flags, rc: self.onConnect.emit(
                 flags, rc)
@@ -92,6 +98,8 @@
         """
         self.__mqttClient.reinitialise(
             client_id=clientId, clean_session=cleanSession, userdata=userdata)
+        
+        self.__initCallbacks()
     
     def setMaxInflightMessages(self, inflight=20):
         """
diff -r 7e0e921dc7ea -r 90d3ebed4cc0 MqttMonitor/MqttConnectionOptionsDialog.py
--- a/MqttMonitor/MqttConnectionOptionsDialog.py	Sat Sep 01 20:18:11 2018 +0200
+++ b/MqttMonitor/MqttConnectionOptionsDialog.py	Sun Sep 02 18:29:35 2018 +0200
@@ -1,12 +1,15 @@
 # -*- coding: utf-8 -*-
 
+# Copyright (c) 2018 Detlev Offenbach <detlev@die-offenbachs.de>
+#
+
 """
 Module implementing a dialog to enter MQTT connection options.
 """
 
 from __future__ import unicode_literals
 
-from PyQt5.QtCore import pyqtSlot
+from PyQt5.QtCore import pyqtSlot, QUuid
 from PyQt5.QtWidgets import QDialog, QDialogButtonBox, QAbstractButton
 
 from .Ui_MqttConnectionOptionsDialog import Ui_MqttConnectionOptionsDialog
@@ -23,7 +26,9 @@
         @param client reference to the MQTT client object
         @type MqttClient
         @param options dictionary containing the connection options to
-            populate the dialog with
+            populate the dialog with. It must have the keys "ClientId",
+            "Keepalive", "CleanSession", "Username", "Password", "WillTopic",
+            "WillMessage", "WillQos", "WillRetain".
         @@type dict
         @param parent reference to the parent widget
         @type QWidget
@@ -34,7 +39,14 @@
         self.__client = client
         
         self.__populateDefaults(options=options)
-        
+    
+    @pyqtSlot()
+    def on_generateIdButton_clicked(self):
+        """
+        Private slot to generate a client ID.
+        """
+        uuid = QUuid.createUuid()
+        self.clientIdEdit.setText(uuid.toString(QUuid.WithoutBraces))
     
     @pyqtSlot(QAbstractButton)
     def on_buttonBox_clicked(self, button):
@@ -53,6 +65,12 @@
         
         If no options dictionary is given, the dialog will be populated with
         default values.
+        
+        @param options dictionary containing the connection options to populate
+            the dialog with. It must have the keys "ClientId", "Keepalive",
+            "CleanSession", "Username", "Password", "WillTopic", "WillMessage",
+            "WillQos", "WillRetain".
+        @type dict
         """
         if options is None:
             options = self.__client.defaultConnectionOptions()
@@ -78,7 +96,7 @@
         
         @return dictionary containing the connection options. It has the keys
             "ClientId", "Keepalive", "CleanSession", "Username", "Password",
-            "WillTopic", "WillMessage", "WillQos", "WillRetain"
+            "WillTopic", "WillMessage", "WillQos", "WillRetain".
         @rtype tuple of (int, dict)
         """
         return {
diff -r 7e0e921dc7ea -r 90d3ebed4cc0 MqttMonitor/MqttConnectionOptionsDialog.ui
--- a/MqttMonitor/MqttConnectionOptionsDialog.ui	Sat Sep 01 20:18:11 2018 +0200
+++ b/MqttMonitor/MqttConnectionOptionsDialog.ui	Sun Sep 02 18:29:35 2018 +0200
@@ -6,7 +6,7 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>400</width>
+    <width>550</width>
     <height>600</height>
    </rect>
   </property>
@@ -37,6 +37,16 @@
         </property>
        </widget>
       </item>
+      <item row="0" column="2">
+       <widget class="QPushButton" name="generateIdButton">
+        <property name="toolTip">
+         <string>Press to generate a client ID</string>
+        </property>
+        <property name="text">
+         <string>Generate</string>
+        </property>
+       </widget>
+      </item>
       <item row="1" column="0">
        <widget class="QLabel" name="label_2">
         <property name="text">
@@ -44,7 +54,7 @@
         </property>
        </widget>
       </item>
-      <item row="1" column="1">
+      <item row="1" column="1" colspan="2">
        <layout class="QHBoxLayout" name="horizontalLayout">
         <item>
          <widget class="QSpinBox" name="keepaliveSpinBox">
@@ -80,7 +90,7 @@
         </item>
        </layout>
       </item>
-      <item row="2" column="0" colspan="2">
+      <item row="2" column="0" colspan="3">
        <widget class="QCheckBox" name="cleanSessionCheckBox">
         <property name="text">
          <string>Clean Session</string>
@@ -135,62 +145,45 @@
      <property name="title">
       <string>Last Will and Testament</string>
      </property>
-     <layout class="QVBoxLayout" name="verticalLayout">
-      <item>
-       <layout class="QHBoxLayout" name="horizontalLayout_2">
-        <item>
-         <spacer name="horizontalSpacer_2">
-          <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="QLabel" name="label_5">
-          <property name="text">
-           <string>QoS:</string>
-          </property>
-         </widget>
-        </item>
-        <item>
-         <widget class="QSpinBox" name="willQosSpinBox">
-          <property name="toolTip">
-           <string>Enter the desired QoS value</string>
-          </property>
-          <property name="alignment">
-           <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
-          </property>
-          <property name="maximum">
-           <number>2</number>
-          </property>
-         </widget>
-        </item>
-        <item>
-         <widget class="QCheckBox" name="willRetainCheckBox">
-          <property name="toolTip">
-           <string>Select to retain the last will message</string>
-          </property>
-          <property name="text">
-           <string>Retain</string>
-          </property>
-         </widget>
-        </item>
-       </layout>
-      </item>
-      <item>
+     <layout class="QGridLayout" name="gridLayout_3">
+      <item row="0" column="0">
        <widget class="QLineEdit" name="willTopicEdit">
         <property name="toolTip">
          <string>Enter the topic of the last will</string>
         </property>
        </widget>
       </item>
-      <item>
+      <item row="0" column="1">
+       <widget class="QLabel" name="label_5">
+        <property name="text">
+         <string>QoS:</string>
+        </property>
+       </widget>
+      </item>
+      <item row="0" column="2">
+       <widget class="QSpinBox" name="willQosSpinBox">
+        <property name="toolTip">
+         <string>Enter the desired QoS value</string>
+        </property>
+        <property name="alignment">
+         <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+        </property>
+        <property name="maximum">
+         <number>2</number>
+        </property>
+       </widget>
+      </item>
+      <item row="0" column="3">
+       <widget class="QCheckBox" name="willRetainCheckBox">
+        <property name="toolTip">
+         <string>Select to retain the last will message</string>
+        </property>
+        <property name="text">
+         <string>Retain</string>
+        </property>
+       </widget>
+      </item>
+      <item row="1" column="0" colspan="4">
        <widget class="QPlainTextEdit" name="willMessageEdit">
         <property name="maximumSize">
          <size>
@@ -227,14 +220,15 @@
  </customwidgets>
  <tabstops>
   <tabstop>clientIdEdit</tabstop>
+  <tabstop>generateIdButton</tabstop>
   <tabstop>keepaliveSpinBox</tabstop>
   <tabstop>cleanSessionCheckBox</tabstop>
   <tabstop>usernameEdit</tabstop>
   <tabstop>passwordEdit</tabstop>
+  <tabstop>willTopicEdit</tabstop>
+  <tabstop>willMessageEdit</tabstop>
   <tabstop>willQosSpinBox</tabstop>
   <tabstop>willRetainCheckBox</tabstop>
-  <tabstop>willTopicEdit</tabstop>
-  <tabstop>willMessageEdit</tabstop>
  </tabstops>
  <resources/>
  <connections>
diff -r 7e0e921dc7ea -r 90d3ebed4cc0 MqttMonitor/MqttMonitorWidget.py
--- a/MqttMonitor/MqttMonitorWidget.py	Sat Sep 01 20:18:11 2018 +0200
+++ b/MqttMonitor/MqttMonitorWidget.py	Sun Sep 02 18:29:35 2018 +0200
@@ -164,6 +164,8 @@
         self.brokerStatusButton.setEnabled(True)
         
         self.__statusLoadValues.clear()
+        self.__clearBrokerStatusLabels()
+        self.__setBrokerStatusSubscribed(False)
     
     @pyqtSlot(int)
     def __brokerDisconnected(self, rc):
@@ -322,7 +324,11 @@
                 port = 1883
             if host:
                 self.__addBrokerToRecent(host, port)
-                self.__client.connectToServer(host, port=port)
+                if self.__connectionOptions is None:
+                    self.__client.connectToServer(host, port=port)
+                else:
+                    self.__client.connectToServerWithOptions(
+                        host, port=port, options=self.__connectionOptions)
     
     @pyqtSlot(str)
     def on_subscribeTopicEdit_textChanged(self, topic):
@@ -403,6 +409,16 @@
             self.__updatePublishTopicComboBox()
     
     @pyqtSlot()
+    def on_publishClearButton_clicked(self):
+        """
+        Private slot to clear the publish data fields.
+        """
+        self.publishTopicComboBox.clearEditText()
+        self.publishPayloadEdit.clear()
+        self.publishQosSpinBox.setValue(0)
+        self.publishRetainCheckBox.setChecked(False)
+    
+    @pyqtSlot()
     def on_brokerStatusButton_clicked(self):
         """
         Private slot to subscribe or unsubscribe the broker status topic.
@@ -413,20 +429,32 @@
                 MqttMonitorWidget.BrokerStatusTopic)
             if rc == 0:
                 # successfully sent
-                self.__brokerStatusTopicSubscribed = False
-                self.brokerStatusButton.setText(self.tr("Subscribe"))
-                self.brokerStatusButton.setToolTip(
-                    self.tr("Press to activate the status display"))
+                self.__setBrokerStatusSubscribed(False)
         else:
             # subscribe status topic
             rc, _ = self.__client.subscribe(
                 MqttMonitorWidget.BrokerStatusTopic)
             if rc == 0:
                 # successfully sent
-                self.__brokerStatusTopicSubscribed = True
-                self.brokerStatusButton.setText(self.tr("Unsubscribe"))
-                self.brokerStatusButton.setToolTip(
-                    self.tr("Press to deactivate the status display"))
+                self.__setBrokerStatusSubscribed(True)
+    
+    def __setBrokerStatusSubscribed(self, subscribed):
+        """
+        Private method to set the subscription status for the broker status
+        topics.
+        
+        @param subscribed subscription status for the broker status topics
+        @type bool
+        """
+        self.__brokerStatusTopicSubscribed = subscribed
+        if subscribed:
+            self.brokerStatusButton.setText(self.tr("Unsubscribe"))
+            self.brokerStatusButton.setToolTip(
+                self.tr("Press to deactivate the status display"))
+        else:
+            self.brokerStatusButton.setText(self.tr("Subscribe"))
+            self.brokerStatusButton.setToolTip(
+                self.tr("Press to activate the status display"))
     
     #######################################################################
     ## Utility methods
@@ -470,10 +498,10 @@
         else:
             currentPort = 1883
         currentPortStr = "{0:5}".format(currentPort)
-        portsSet = set([b[1] for b in brokerList])
-        portsSet.update([1883, 8883])
+        portsSet = {b[1] for b in brokerList}
+        portsSet.update({1883, 8883})
         self.brokerPortComboBox.addItems(
-            sorted(["{0:5}".format(p) for p in portsSet]))
+            sorted("{0:5}".format(p) for p in portsSet))
         index = self.brokerPortComboBox.findText(currentPortStr)
         self.brokerPortComboBox.setCurrentIndex(index)
     
@@ -559,6 +587,18 @@
             # ignore topics not shown in display
             pass
     
+    def __clearBrokerStatusLabels(self):
+        """
+        Private method to clear the broker status labels.
+        """
+        for statusLabelKey in self.__statusLabelMapping:
+            if statusLabelKey.startswith(
+                    MqttMonitorWidget.BrokerStatusTopicLoadPrefix):
+                label = "- / - / -"
+            else:
+                label = "-"
+            self.__statusLabelMapping[statusLabelKey].setText(label)
+    
     def __loadDefaultDictFactory(self):
         """
         Private method to populate non-existing load items.
diff -r 7e0e921dc7ea -r 90d3ebed4cc0 MqttMonitor/MqttMonitorWidget.ui
--- a/MqttMonitor/MqttMonitorWidget.ui	Sat Sep 01 20:18:11 2018 +0200
+++ b/MqttMonitor/MqttMonitorWidget.ui	Sun Sep 02 18:29:35 2018 +0200
@@ -280,6 +280,16 @@
           <item>
            <layout class="QHBoxLayout" name="horizontalLayout_12">
             <item>
+             <widget class="QPushButton" name="publishClearButton">
+              <property name="toolTip">
+               <string>Press to clear the publish data</string>
+              </property>
+              <property name="text">
+               <string>Clear</string>
+              </property>
+             </widget>
+            </item>
+            <item>
              <spacer name="horizontalSpacer_3">
               <property name="orientation">
                <enum>Qt::Horizontal</enum>

eric ide

mercurial