@knautschkissen: In Queues kannst Du beliebige Objekte tun, diese Aufteilung auf drei Queues scheint also nicht sinnvoll zu sein.
Nackte ``except``\s ohne konkrete Ausnahemen anzugeben ist eine ganz schlechte Idee. Du erwartest da nur ein `queue.Empty` bei der nicht-blockierenden Variante, und auch nur das sollte dann durch totales ignorieren behandelt werden, falls das eine sinnvolle Behandlung dafür ist. Alle anderen Ausnahmen sollten weiterhin ganz normale Folgen haben. Sonst macht man sich die Fehlersuche nur unnötig schwer.
Wenn man in einem Zweig nichts machen will, da aber aus syntaktischen Gründen etwas stehen muss, verwendet man das Schlüsselwort ``pass`` und nicht irgendeinen Wert. Ich würde da auch immer einen Kommentar dran schreiben warum das okay ist da nichts zu tun, oder zumindest deutlich machen, dass das Absicht ist, und da nicht einfach nur Code fehlt der noch nicht geschrieben wurde.
`QtGui`, `QtCore`, `QThread` und `pyqtSignal` werden importiert, aber nirgends verwendet.
Code generieren ist eigentlich nicht mehr nötig/üblich, man kann die `*.ui`-Datei die der Qt-Designer speichert zur Laufzeit mit Hilfe des `PyQt5.uic`-Moduls laden.
`super()` braucht *gar keine* Argumente, aber auf jeden Fall eher nicht `self.__class__`, denn das funktioniert bei Vererbung nicht richtig.
Namenskonvention bei Python ist klein_mit_unterstrichen für alles ausser Konstanten (KOMPLETT_GROSS) und Klassen (MixedCase). Bibliotheken wie `PyQt5` verstossen dagegen weil die darunterliegende Bibliothek in einer anderen Programmiersprache geschrieben ist, und deshalb die Namen von dort übernommen wurden, statt alles umzubennenen, was arbeit macht, zu Fehlern/Problemen führen kann, und dann auch von der Qt-Dokumentation abweichen würde. Man kann sich dann überlegen ob man beim reinen GUI-Code auch diese Konvention übernimmt, aber `Befehl` wäre als Name für einen Wert in beiden Namenskonventionen falsch. Und man sollte kryptische Abkürzungen und Prä-/und Suffixe vermeiden. Also anstatt `q_Befehl` besser `befehls_queue` schreiben. Insbesondere kann das `q_` auch im Zusammenhang mit Qt beim Leser zu Verwirrung führen.
*Eine* Sprache bei den Namen wäre gut. Mir ist zum Beispiel nicht ersichtlich warum es ausgerechnet `befehl` und `value` heisst und nicht `command` und `value` oder `command` und `wert`.
Das mit dem Thread wird so nicht funktionieren. In einer Schleife dauerhaft den Prozessor damit zu beschäftigen auf einen Zeitpunkt zu warten ist auch keine gute Idee. Neben dem unnötigen Verbrauch von Rechenzeit ist das auch sehr unpräzise. Zudem gibt es keine `time_ns()`-Funktion.
Man sollte keine Zahlen als literale Wahrheitswerte missbrauchen. Python hat dafür extra `True` und `False`.
Bei `Queue.get()` die Argumente `block` *und* `timeout` anzugeben ist überflüssig. Wenn man einen Wert für die Zeitüberschreitung übergibt, dann macht es keinen Sinn `block` auf `False` zu setzen. Oder eben umgekehrt, wenn man den Aufruf nicht blockierend haven will, macht es keinen Sinn zu sagen wie lange maximal blockiert werden soll.
Wenn man alles aus der Klasse raus wirft was keinen Sinn macht, bleibt die `__init__()` wo die Queue übergeben wird, und die `run()`. Also eigentlich nicht mehr wirklich eine Klasse, sondern eine Funktion.
Ungetestet:
Code: Alles auswählen
#!/usr/bin/env python3
from functools import partial
from queue import Empty, Queue
import sys
from threading import Thread
from attr import attrib, attrs
from PyQt5 import QtWidgets
import GUI
@attrs(frozen=True)
class Command:
command = attrib()
value = attrib(default=None)
address = attrib(default=None)
class Gui(QtWidgets.QMainWindow, GUI.Ui_Form):
def __init__(self, command_queue):
super().__init__()
self.setupUi(self)
self.command_queue = command_queue
self.M_Azi_Left.clicked.connect(
partial(self.put_command, "M_Azi_Left_clicked")
)
self.M_Azi_Right.clicked.connect(
partial(self.put_command, "M_Azi_Right_clicked")
)
self.M_Azi_Zero.clicked.connect(
partial(self.put_command, "M_Azi_Zero_clicked")
)
self.M_Pitch_Up.clicked.connect(
partial(self.put_command, "M_Pitch_Up_clicked")
)
self.M_Pitch_Down.clicked.connect(
partial(self.put_command, "M_Pitch_Down_clicked")
)
self.M_Pitch_Zero.clicked.connect(
partial(self.put_command, "M_Pitch_Zero_clicked")
)
self.Azi_MinMax_Fast_Low.clicked.connect(
partial(self.put_command, "Azi_MinMax_Fast_Low_clicked")
)
self.Azi_MinMax_Low.clicked.connect(
partial(self.put_command, "Azi_MinMax_Low_clicked")
)
self.Azi_MinMax_Fast_Up.clicked.connect(
partial(self.put_command, "Azi_MinMax_Fast_Up_clicked")
)
self.Azi_MinMax_Up.clicked.connect(
partial(self.put_command, "Azi_MinMax_Up_clicked")
)
self.RotSpeed_Min_Fast_Low.clicked.connect(
partial(self.put_command, "RotSpeed_Min_Fast_Low_clicked")
)
self.RotSpeed_Min_Low.clicked.connect(
partial(self.put_command, "RotSpeed_Min_Low_clicked")
)
self.RotSpeed_Min_Fast_Up.clicked.connect(
partial(self.put_command, "RotSpeed_Min_Fast_Up_clicked")
)
self.RotSpeed_Min_Up.clicked.connect(
partial(self.put_command, "RotSpeed_Min_Up_clicked")
)
self.RotSpeed_Max_Fast_Low.clicked.connect(
partial(self.put_command, "RotSpeed_Max_Fast_Low_clicked")
)
self.RotSpeed_Max_Low.clicked.connect(
partial(self.put_command, "RotSpeed_Max_Low_clicked")
)
self.RotSpeed_Max_Fast_Up.clicked.connect(
partial(self.put_command, "RotSpeed_Max_Fast_Up_clicked")
)
self.RotSpeed_Max_Up.clicked.connect(
partial(self.put_command, "RotSpeed_Max_Up_clicked")
)
self.Btn_Start.clicked.connect(
partial(self.put_command, "Btn_Start_clicked")
)
self.Btn_Stop.clicked.connect(
partial(self.put_command, "Btn_Stop_clicked")
)
self.ScrollBar_Pitch.valueChanged.connect(
partial(self._put_command, "ScrollBar_Pitch_value")
)
self.ScrollBar_Azi.valueChanged.connect(
partial(self._put_command, "ScrollBar_Azi_value")
)
self.ScrollBar_Speed.valueChanged.connect(
partial(self._put_command, "ScrollBar_Speed_value")
)
self.tabWidget.currentChanged.connect(
partial(self.put_command, "tabWidget_changed")
)
def do_something(self):
print("hab was getan")
self.lcdNumber_Azi_MinMax.display(self.ScrollBar_Pitch.value())
def put_command(self, command, value=None, address=None):
self.command_queue.put(Command(command, value, address))
def process_commands(command_queue):
while True:
try:
try:
print(command_queue.get(timeout=0.5))
finally:
command_queue.task_done()
except Empty:
print("500ms sind vergangen")
def main():
command_queue = Queue()
command_thread = Thread(
target=process_commands, args=[command_queue], daemon=True
)
command_thread.start()
command_queue.put(Command("putBefehl", "putValuev", "putAdresse"))
app = QtWidgets.QApplication(sys.argv)
gui = Gui(command_queue)
gui.show()
app.exec_()
command_thread.join()
if __name__ == "__main__":
main()