Projekt

Obecné

Profil

« Předchozí | Další » 

Revize 7d28568e

Přidáno uživatelem Martin Forejt před téměř 4 roky(ů)

Re: #8921 - settings dialog

Zobrazit rozdíly:

aswi2021vochomurka/service/mqtt/mqtt_subscriber.py
7 7

  
8 8

  
9 9
class MQTTSubscriber(Subscriber):
10
    client: mqtt.Client = None
10 11

  
11 12
    # The callback for when the client receives a CONNACK response from the server.
12 13
    def on_connect(self, client, userdata, flags, rc, properties=None):
......
40 41
    def start(self):
41 42
        super().start()
42 43
        client = mqtt.Client()
44
        self.client = client
43 45
        client.on_connect = self.on_connect
44 46
        client.on_message = self.on_message
45 47
        client.on_disconnect = self.on_disconnect
......
63 65
            return
64 66

  
65 67
        client.loop_forever()
68

  
69
    def stop(self):
70
        super().stop()
71
        if self.client is not None:
72
            logging.info("Disconnecting from broker")
73
            client = self.client
74
            self.client = None
75
            client.disconnect()
aswi2021vochomurka/service/subscriber.py
1 1
import time
2
from typing import Dict
2 3

  
3 4
from apscheduler.schedulers.background import BackgroundScheduler
5
from apscheduler.schedulers.base import STATE_STOPPED
4 6

  
5 7
from aswi2021vochomurka.model.Message import Message
6 8
from aswi2021vochomurka.service.file_manager import FileManager
7 9
from aswi2021vochomurka.service.subscriber_callback import SubscriberCallback
8 10
from aswi2021vochomurka.service.subscriber_params import SubscriberParams
9
from typing import Dict
10 11

  
11 12

  
12 13
class Subscriber:
13 14
    callback: SubscriberCallback
14 15
    params: SubscriberParams
15 16

  
16
    scheduler = BackgroundScheduler()
17
    scheduler: BackgroundScheduler
17 18
    files: Dict[str, FileManager] = {}
18 19

  
19 20
    def __init__(self, callback: SubscriberCallback, params: SubscriberParams):
......
22 23

  
23 24
    def start(self):
24 25
        # start scheduler to check closed topics
26
        self.scheduler = BackgroundScheduler()
25 27
        self.scheduler.add_job(self.check_closed_topics, 'interval', seconds=self.params.closeLimit)
26 28
        self.scheduler.start()
27 29

  
28 30
    def stop(self):
29
        self.scheduler.shutdown()
31
        if self.scheduler.state != STATE_STOPPED:
32
            self.scheduler.shutdown()
30 33
        self.close_files()
31 34

  
32 35
    def close_files(self):
33 36
        for topic in self.files:
34 37
            self.files.get(topic).close()
35
        self.files = {}
38
        self.files.clear()
36 39

  
37 40
    def check_closed_topics(self):
38 41
        t = time.time()
aswi2021vochomurka/view/main_view.py
2 2
import math
3 3

  
4 4
import matplotlib.pyplot as plt
5
from PyQt5 import QtGui
5 6
from PyQt5.QtCore import QSize, QThread, QObject, pyqtSignal
6 7
from PyQt5.QtWidgets import QMainWindow, QWidget, QMenuBar, QAction
7 8
from PyQt5.QtWidgets import QVBoxLayout
......
23 24
    connected = pyqtSignal()
24 25
    disconnected = pyqtSignal()
25 26
    error = pyqtSignal(Exception)
26
    newMessage = pyqtSignal(str)
27
    newMessage = pyqtSignal(Message)
27 28
    subscriber: Subscriber = None
28 29

  
29 30
    params = SubscriberParams(
......
37 38
        self.subscriber = MQTTSubscriber(self, self.params)
38 39
        self.subscriber.start()
39 40

  
41
    def stop(self):
42
        self.subscriber.stop()
43

  
40 44
    def onConnected(self):
41 45
        self.connected.emit()
42 46

  
......
47 51
        self.error.emit()
48 52

  
49 53
    def onMessage(self, message: Message):
50
        self.newMessage.emit(message.topic)
51
        self.window.plot(message)
54
        self.newMessage.emit(message)
55
        pass
52 56

  
53 57
    def onCloseTopic(self, topic: str):
54 58
        pass
......
128 132

  
129 133
        self.canvas.draw()
130 134

  
135
    def closeEvent(self, a0: QtGui.QCloseEvent) -> None:
136
        self.worker.stop()
137

  
131 138
    def settings(self):
132 139
        dialog = SettingsDialog()
133
        dialog.exec_()
140
        if dialog.exec_():
141
            self.reconnect()
134 142

  
135 143
    def help(self):
136 144
        dialog = HelpDialog()
......
141 149
        dialog = AboutDialog()
142 150
        dialog.exec_()
143 151

  
152
    def disconnect(self):
153
        self.worker.stop()
154
        self.workerThread.quit()
155
        self.workerThread.wait()
156

  
157
    def reconnect(self):
158
        self.disconnect()
159
        self.workerThread.start()
160

  
144 161
    def initSubscriber(self):
145 162
        self.workerThread = QThread()
146 163
        self.worker = Worker()
147 164
        self.worker.moveToThread(self.workerThread)
148 165
        self.workerThread.started.connect(self.worker.start)
149
        # self.worker.newMessage.connect(
150
        #    lambda message: self.b.insertPlainText(message + "\n")
151
        # )
152
        self.worker.window = self
166
        self.worker.newMessage.connect(
167
            lambda message: self.plot(message)
168
        )
153 169
        self.workerThread.start()
aswi2021vochomurka/view/settings.py
1
from PyQt5.QtWidgets import QDialog
1
from PyQt5 import QtCore
2
from PyQt5.QtCore import QSettings, QSize
3
from PyQt5.QtGui import QStandardItemModel, QStandardItem
4
from PyQt5.QtWidgets import QDialog, QVBoxLayout, QDialogButtonBox, QGroupBox, QFormLayout, QLabel, QLineEdit, QSpinBox, \
5
    QCheckBox, QListView, QWidget, QPushButton, QHBoxLayout, QListWidget, QListWidgetItem, QTableWidget
2 6

  
3 7

  
4 8
class SettingsDialog(QDialog):
9
    topics = ['/home/1', '/home/2']
10

  
5 11
    def __init__(self):
6 12
        super(SettingsDialog, self).__init__()
7

  
13
        self.settings = QSettings("Vochomurka", "MQTTClient")
8 14
        self.setWindowTitle("Settings")
15
        self.setMinimumSize(QSize(600, 500))
16

  
17
        connectionGroupBox = QGroupBox("Connection")
18
        connectionLayout = QFormLayout()
19
        self.hostInput = QLineEdit(self.settings.value("connection_host", "localhost", str))
20
        connectionLayout.addRow(QLabel("Host:"), self.hostInput)
21
        self.portInput = QSpinBox()
22
        self.portInput.setMaximum(65535)
23
        self.portInput.setValue(self.settings.value("connection_port", 1883, int))
24
        connectionLayout.addRow(QLabel("Port:"), self.portInput)
25
        self.keepaliveInput = QSpinBox()
26
        self.keepaliveInput.setMaximum(1000)
27
        self.keepaliveInput.setValue(self.settings.value("connection_keepalive", 60, int))
28
        connectionLayout.addRow(QLabel("Keepalive(s):"), self.keepaliveInput)
29
        self.anonymousInput = QCheckBox()
30
        self.anonymousInput.setChecked(self.settings.value("connection_anonymous", True, bool))
31
        self.anonymousInput.stateChanged.connect(self.anonymousChanged)
32
        connectionLayout.addRow(QLabel("Anonymous:"), self.anonymousInput)
33
        self.usernameInput = QLineEdit(self.settings.value("connection_username", "", str))
34
        connectionLayout.addRow(QLabel("Username:"), self.usernameInput)
35
        self.passwordInput = QLineEdit(self.settings.value("connection_password", "", str))
36
        connectionLayout.addRow(QLabel("Password:"), self.passwordInput)
37
        self.anonymousChanged()
38
        connectionGroupBox.setLayout(connectionLayout)
39

  
40
        topicsGroupBox = QGroupBox("Topics")
41
        topicsLayout = QFormLayout()
42

  
43
        self.topicsListWidget = QListWidget()
44
        for topic in self.topics:
45
            item = QListWidgetItem()
46
            item.setText(topic)
47
            item.setFlags(item.flags() | QtCore.Qt.ItemIsEditable)
48
            self.topicsListWidget.addItem(item)
49

  
50
        topicsLayout.addRow(self.topicsListWidget)
51
        add = QPushButton("Add")
52
        add.setFixedWidth(60)
53
        add.clicked.connect(self.addTopic)
54
        remove = QPushButton("Remove")
55
        remove.setFixedWidth(60)
56
        remove.clicked.connect(self.removeTopic)
57
        topicsLayout.addRow(add, remove)
58

  
59
        self.timeoutInput = QSpinBox()
60
        self.timeoutInput.setMaximum(1000)
61
        self.timeoutInput.setToolTip("Unsubscribe topic and close file when there is not new message after this "
62
                                     "timeout (in seconds) expires")
63
        timeoutLabel = QLabel("Topic timeout(s):")
64
        timeoutLabel.setToolTip("Unsubscribe topic and close file when there is not new message after this "
65
                                "timeout (in seconds) expires")
66
        self.timeoutInput.setValue(self.settings.value("topic_timeout", 60, int))
67
        topicsLayout.addRow(timeoutLabel, self.timeoutInput)
68

  
69
        topicsGroupBox.setLayout(topicsLayout)
70

  
71
        buttonBox = QDialogButtonBox()
72
        buttonBox.addButton("Save and Reconnect", QDialogButtonBox.AcceptRole)
73
        buttonBox.addButton("Cancel", QDialogButtonBox.RejectRole)
74
        buttonBox.accepted.connect(self.accept)
75
        buttonBox.rejected.connect(self.reject)
76

  
77
        mainLayout = QVBoxLayout()
78
        mainLayout.addWidget(connectionGroupBox)
79
        mainLayout.addWidget(topicsGroupBox)
80
        mainLayout.addWidget(buttonBox)
81
        self.setLayout(mainLayout)
82

  
83
    def addTopic(self):
84
        item = QListWidgetItem()
85
        item.setText("/topic")
86
        item.setFlags(item.flags() | QtCore.Qt.ItemIsEditable)
87
        self.topicsListWidget.addItem(item)
88

  
89
    def removeTopic(self):
90
        for item in self.topicsListWidget.selectedItems():
91
            self.topicsListWidget.takeItem(self.topicsListWidget.row(item))
92

  
93
    def anonymousChanged(self):
94
        self.usernameInput.setEnabled(not self.anonymousInput.isChecked())
95
        self.passwordInput.setEnabled(not self.anonymousInput.isChecked())
96

  
97
    def accept(self) -> None:
98
        super().accept()
99
        self.topics = self.topicsListWidget.item(0).text()
100
        print(self.topics)
101
        self.settings.setValue("connection_host", self.hostInput.text())
102
        self.settings.setValue("connection_port", self.portInput.value())
103
        self.settings.setValue("connection_keepalive", self.keepaliveInput.value())
104
        self.settings.setValue("connection_anonymous", self.anonymousInput.isChecked())
105
        self.settings.setValue("connection_username", self.usernameInput.text())
106
        self.settings.setValue("connection_password", self.passwordInput.text())

Také k dispozici: Unified diff