MqttMonitorWidget: added functionality to subscribe to and unsubscribe from topics.

Tue, 28 Aug 2018 18:54:48 +0200

author
Detlev Offenbach <detlev@die-offenbachs.de>
date
Tue, 28 Aug 2018 18:54:48 +0200
changeset 4
991db89bda9c
parent 3
82845c0fd550
child 5
7162c838cfc9

MqttMonitorWidget: added functionality to subscribe to and unsubscribe from topics.

MqttMonitor/MqttMonitorWidget.py file | annotate | diff | comparison | revisions
MqttMonitor/MqttMonitorWidget.ui file | annotate | diff | comparison | revisions
--- a/MqttMonitor/MqttMonitorWidget.py	Mon Aug 27 19:26:27 2018 +0200
+++ b/MqttMonitor/MqttMonitorWidget.py	Tue Aug 28 18:54:48 2018 +0200
@@ -49,6 +49,14 @@
             self.__plugin.getPreferences("RecentBrokers"))
         self.brokerStatusLabel.hide()
         
+        self.subscribeButton.setIcon(UI.PixmapCache.getIcon("plus.png"))
+        self.subscribeButton.setEnabled(False)
+        self.unsubscribeButton.setIcon(UI.PixmapCache.getIcon("minus.png"))
+        
+        self.__subscribedTopics = []
+        self.__topicQueue = {}
+        self.__updateUnsubscribeTopicComboBox()
+        
         self.__client = MqttClient()
         
         # connect the MQTT client signals
@@ -80,6 +88,9 @@
         self.__flashBrokerStatusLabel(msg)
         
         self.connectButton.setIcon(UI.PixmapCache.getIcon("ircDisconnect.png"))
+        
+        self.subscribeGroup.setEnabled(True)
+        self.unsubscribeGroup.setEnabled(True)
     
     @pyqtSlot(int)
     def __brokerDisconnected(self, rc):
@@ -91,6 +102,9 @@
         """
         self.__connectedToBroker = False
         
+        # ensure, the client loop is stopped
+        self.__client.stopLoop()
+        
         if rc != 0:
             msg = mqttErrorMessage(rc)
         else:
@@ -98,8 +112,13 @@
         self.__flashBrokerStatusLabel(msg)
         
         self.connectButton.setIcon(UI.PixmapCache.getIcon("ircConnect.png"))
+
+        self.__subscribedTopics = []
+        self.__topicQueue = {}
+        self.__updateUnsubscribeTopicComboBox()
         
-        self.__client.stopLoop()
+        self.subscribeGroup.setEnabled(False)
+        self.unsubscribeGroup.setEnabled(False)
     
     @pyqtSlot(str, bytes, int, bool)
     def __messageReceived(self, topic, payload, qos, retain):
@@ -137,7 +156,12 @@
         @param grantedQos tuple of granted quality of service
         @type tuple of int
         """
-        pass
+        if mid in self.__topicQueue:
+            topic = self.__topicQueue.pop(mid)
+            self.__subscribedTopics.append(topic)
+            self.subscribeTopicEdit.clear()
+            
+            self.__updateUnsubscribeTopicComboBox()
     
     @pyqtSlot(int)
     def __topicUnsubscribed(self, mid):
@@ -147,7 +171,14 @@
         @param mid ID of the unsubscribe request
         @type int
         """
-        pass
+        if mid in self.__topicQueue:
+            topic = self.__topicQueue.pop(mid)
+            try:
+                self.__subscribedTopics.remove(topic)
+                self.__updateUnsubscribeTopicComboBox()
+            except ValueError:
+                # ignore it
+                pass
     
     #######################################################################
     ## Slots handling UI interactions
@@ -188,8 +219,51 @@
             self.__client.disconnectFromServer()
         else:
             host = self.brokerComboBox.currentText()
-            self.__addBrokerToRecent(host)
-            self.__client.connectToServer(host)     # use standard port at 1883
+            if host:
+                self.__addBrokerToRecent(host)
+                self.__client.connectToServer(host)
+                # use standard port at 1883
+    
+    @pyqtSlot(str)
+    def on_subscribeTopicEdit_textChanged(self, topic):
+        """
+        Private slot to handle a change of the entered topic.
+        
+        @param topic entered topic text
+        @type str
+        """
+        self.subscribeButton.setEnabled(bool(topic))
+    
+    @pyqtSlot()
+    def on_subscribeButton_clicked(self):
+        """
+        Private slot to subscribe to the entered topic.
+        """
+        topic = self.subscribeTopicEdit.text()
+        qos = self.subscribeQosSpinBox.value()
+        if topic:
+            self.__topicQueue[
+                self.__client.subscribe(topic, qos)[1]] = topic
+    
+    @pyqtSlot(str)
+    def on_unsubscribeTopicComboBox_currentIndexChanged(self, topic):
+        """
+        Private slot to handle the selection of a topic to unsubscribe from.
+        
+        @param topic topic text
+        @type str
+        """
+        self.unsubscribeButton.setEnabled(bool(topic))
+    
+    @pyqtSlot()
+    def on_unsubscribeButton_clicked(self):
+        """
+        Private slot to unsubscribe from the selected topic.
+        """
+        topic = self.unsubscribeTopicComboBox.currentText()
+        if topic:
+            self.__topicQueue[
+                self.__client.unsubscribe(topic)[1]] = topic
     
     #######################################################################
     ## Utility methods
@@ -211,3 +285,11 @@
         
         self.brokerComboBox.clear()
         self.brokerComboBox.addItems(brokerList)
+    
+    def __updateUnsubscribeTopicComboBox(self):
+        """
+        Private method to update the unsubcribe topic combo box.
+        """
+        self.unsubscribeTopicComboBox.clear()
+        self.unsubscribeTopicComboBox.addItems(sorted(self.__subscribedTopics))
+        self.unsubscribeButton.setEnabled(len(self.__subscribedTopics) > 0)
--- a/MqttMonitor/MqttMonitorWidget.ui	Mon Aug 27 19:26:27 2018 +0200
+++ b/MqttMonitor/MqttMonitorWidget.ui	Tue Aug 28 18:54:48 2018 +0200
@@ -7,7 +7,7 @@
     <x>0</x>
     <y>0</y>
     <width>400</width>
-    <height>300</height>
+    <height>600</height>
    </rect>
   </property>
   <layout class="QVBoxLayout" name="verticalLayout">
@@ -77,20 +77,153 @@
     </widget>
    </item>
    <item>
-    <spacer name="verticalSpacer">
-     <property name="orientation">
-      <enum>Qt::Vertical</enum>
+    <widget class="QTabWidget" name="brokerWidget">
+     <property name="currentIndex">
+      <number>0</number>
      </property>
-     <property name="sizeHint" stdset="0">
-      <size>
-       <width>20</width>
-       <height>251</height>
-      </size>
-     </property>
-    </spacer>
+     <widget class="QWidget" name="pubSubTab">
+      <attribute name="title">
+       <string>Pub/Sub</string>
+      </attribute>
+      <layout class="QVBoxLayout" name="verticalLayout_2">
+       <item>
+        <widget class="QGroupBox" name="subscribeGroup">
+         <property name="enabled">
+          <bool>false</bool>
+         </property>
+         <property name="title">
+          <string>Subscribe</string>
+         </property>
+         <layout class="QHBoxLayout" name="horizontalLayout_2">
+          <item>
+           <widget class="QLabel" name="label">
+            <property name="text">
+             <string>Topic:</string>
+            </property>
+           </widget>
+          </item>
+          <item>
+           <widget class="E5ClearableLineEdit" name="subscribeTopicEdit">
+            <property name="toolTip">
+             <string>Enter the topic</string>
+            </property>
+           </widget>
+          </item>
+          <item>
+           <widget class="QLabel" name="label_3">
+            <property name="text">
+             <string>QoS:</string>
+            </property>
+           </widget>
+          </item>
+          <item>
+           <widget class="QSpinBox" name="subscribeQosSpinBox">
+            <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="QToolButton" name="subscribeButton">
+            <property name="toolTip">
+             <string>Press to subscribe to the given topic</string>
+            </property>
+           </widget>
+          </item>
+         </layout>
+        </widget>
+       </item>
+       <item>
+        <widget class="QGroupBox" name="unsubscribeGroup">
+         <property name="enabled">
+          <bool>false</bool>
+         </property>
+         <property name="title">
+          <string>Unsubscribe</string>
+         </property>
+         <layout class="QHBoxLayout" name="horizontalLayout_3">
+          <item>
+           <widget class="QLabel" name="label_4">
+            <property name="text">
+             <string>Topic:</string>
+            </property>
+           </widget>
+          </item>
+          <item>
+           <widget class="QComboBox" name="unsubscribeTopicComboBox">
+            <property name="sizePolicy">
+             <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+              <horstretch>0</horstretch>
+              <verstretch>0</verstretch>
+             </sizepolicy>
+            </property>
+            <property name="toolTip">
+             <string>Select the topic to unsubscribe</string>
+            </property>
+           </widget>
+          </item>
+          <item>
+           <widget class="QToolButton" name="unsubscribeButton">
+            <property name="toolTip">
+             <string>Press to unsubscribe the selected topic</string>
+            </property>
+           </widget>
+          </item>
+         </layout>
+        </widget>
+       </item>
+       <item>
+        <spacer name="verticalSpacer">
+         <property name="orientation">
+          <enum>Qt::Vertical</enum>
+         </property>
+         <property name="sizeHint" stdset="0">
+          <size>
+           <width>20</width>
+           <height>312</height>
+          </size>
+         </property>
+        </spacer>
+       </item>
+      </layout>
+     </widget>
+     <widget class="QWidget" name="messagesTab">
+      <attribute name="title">
+       <string>Messages</string>
+      </attribute>
+     </widget>
+     <widget class="QWidget" name="statusTab">
+      <attribute name="title">
+       <string>Status</string>
+      </attribute>
+     </widget>
+    </widget>
    </item>
   </layout>
  </widget>
+ <customwidgets>
+  <customwidget>
+   <class>E5ClearableLineEdit</class>
+   <extends>QLineEdit</extends>
+   <header>E5Gui/E5LineEdit.h</header>
+  </customwidget>
+ </customwidgets>
+ <tabstops>
+  <tabstop>brokerComboBox</tabstop>
+  <tabstop>connectButton</tabstop>
+  <tabstop>brokerWidget</tabstop>
+  <tabstop>subscribeTopicEdit</tabstop>
+  <tabstop>subscribeQosSpinBox</tabstop>
+  <tabstop>subscribeButton</tabstop>
+  <tabstop>unsubscribeTopicComboBox</tabstop>
+  <tabstop>unsubscribeButton</tabstop>
+ </tabstops>
  <resources/>
  <connections/>
 </ui>

eric ide

mercurial