Qt Designer와 PyQt5로 GUI인 MQTT 구독자를 만들 때의 메모

소개



직장의 건물이 신축되었으므로, 각 층의 분전반에 전력계를 설치해, 1곳에서 모니터링할 수 있는 시스템을 구축하려고 생각했다.
전력계는 @ arms22 님의 기사을 참고로 제작했다.

시스템의 전체도


개발 환경 구축



Windows10상에, 선인의 지혜를 참고로 환경 구축.
  • Python3 및 PyQt5 설치
  • 【Python으로 GUI】PyQt5 -준비-

  • paho-mqtt는 pip로 설치

    MQTT 브로커 준비



    실행중인 서버에 mosquitto를 설치해도 좋았지 만 Raspberry Pi를 사용하기로 결정했습니다.
    일반적으로 Raspberry Pi를 설정 한 후 apt-get으로 python3, mosquitto를 설치합니다.
    pip로 PyQt5, paho-mqtt를 설치.
    Raspberry Pi의 IP 주소는 정적인 것을 흔들어 둔다.

    UI 디자인



    Qt Designer 시작

    새로운 폼에서는, 「Main Window」를 선택한다. (Dialog라도 좋지만, 그 경우 UI를 표시하는 코드가 조금 바뀝니다)

    적당히 UI를 디자인한다.
    이 예에서는 LCD Number 위젯을 2개 배치해 보았다. 이 때, 각 위젯의 objectName은 알기 쉬운 것으로 바꾸어 두면 길.

    적절한 이름 (test_ui.ui)으로 저장하십시오.

    pyuic5에서 .ui를 .py로 변환



    pyuic5의 설치 경로는 자신의 경우 PyQt5를 설치할 때 --user 옵션을 붙이지 않으면 설치할 수 없었기 때문에 C:\Users\[username]\AppData\Roaming\Python\Python36\Scripts에 들어 있었다.
    다음 명령을 사용하여 .ui 파일을 .py로 변환합니다.
    > pyuic5 test_ui.ui -o test_ui.py
    

    변환 된 .py를 표시하는 코드 작성



    test.py
    import sys
    from PyQt5.QtCore import *
    from PyQt5.QtGui import *
    from PyQt5.QtWidgets import *
    from PyQt5.Qt import *
    from test_ui import Ui_MainWindow
    
    class Test(QMainWindow):
        def __init__(self):
            super(Test, self).__init__()
            self.ui = Ui_MainWindow()
            self.ui.setupUi(self)
    
    if __name__ == '__main__':
        app = QApplication(sys.argv)
        window = Test()
        window.show()
        sys.exit(app.exec())
    

    다음 명령으로 디자인한 UI가 표시되어야 합니다.
    > python test.py
    

    MQTT 코드 삽입



    test.py
    import sys
    from PyQt5.QtCore import *
    from PyQt5.QtGui import *
    from PyQt5.QtWidgets import *
    from PyQt5.Qt import *
    from test_ui import Ui_MainWindow
    import paho.mqtt.client as mqtt
    
    class Test(QMainWindow):
        def __init__(self, mqtt_client):
            super(Test, self).__init__()
            self._mqtt_client = mqtt_client
            self._mqtt_client.on_connect = self.on_connect
            self._mqtt_client.on_message = self.on_message
    
            self.ui = Ui_MainWindow()
            self.ui.setupUi(self)
            # トピックと表示するウィジェットを対応させる辞書
            self.lcd = {
                "test/A": self.ui.lcdTestA,
                "test/B": self.ui.lcdTestB,
            }
    
        def on_message(self, client, userdata, msg):
            print("Topic: " + str(msg.topic))
            print("Message: " + str(msg.payload))
            # 受信したtopicにより対応するwidgetにpayloadを表示する処理
            for i in self.lcd.items():
                if str(i[0]) == str(msg.topic):
                    i[1].display(format("%.1f" % float(msg.payload)))
    
        def on_connect(self, client, userdata, flags, rc):
            print("connected with result code: " + str(rc))
            client.subscribe("#") # 全てのトピックを受信
    
    if __name__ == '__main__':
        client = mqtt.Client()
        app = QApplication(sys.argv)
        window = Test(client)
        window.show()
    
        client.connect('localhost', 1883)
        client.loop_start()
        try:
            sys.exit(app.exec_())
        finally:
            client.loop_stop()
    

    다음 명령으로 UI를 표시합니다.
    python test.py
    

    다른 쉘에서 publish 해보십시오.
    % mosquitto_pub -h localhost -t test/A -m 100
    % mosquitto_pub -h localhost -t test/B -m 3.14
    

    다음과 같이 표시되어야 합니다.


    실제로 만든 것





    표시가 0인 것은 전력계를 설치하지 않은 곳.

    참고로 한 페이지


  • PyQt5와 python3에 의한 GUI 프로그래밍 [6]
  • 좋은 웹페이지 즐겨찾기