Ich habe den folgenden Code, der eine Hintergrundoperation ausführt (scan_value
) während der Aktualisierung eines Fortschrittsbalkens in der ui (progress
). scan_value
iteriert über einen Wert in obj
und gibt jedes Mal, wenn der Wert geändert wird, ein Signal aus (value_changed
). Aus Gründen, die hier nicht relevant sind, muss ich diese in ein Objekt (Scanner
) in einem anderen Thread einbinden. Der Scanner wird aufgerufen, wenn die a-Taste scan
clicked
ist. Und hier kommt meine Frage ... der folgende Code funktioniert gut (d. H. Der Fortschrittsbalken wird rechtzeitig aktualisiert).PyQt: Anschließen eines Signals an einen Steckplatz zum Starten einer Hintergrundoperation
# I am copying only the relevant code here.
def update_progress_bar(new, old):
fraction = (new - start)/(stop - start)
progress.setValue(fraction * 100)
obj.value_changed.connect(update_progress_bar)
class Scanner(QObject):
def scan(self):
scan_value(start, stop, step)
progress.setValue(100)
thread = QThread()
scanner = Scanner()
scanner.moveToThread(thread)
thread.start()
scan.clicked.connect(scanner.scan)
Aber wenn ich den letzten Teil dazu ändern:
thread = QThread()
scanner = Scanner()
scan.clicked.connect(scanner.scan) # This was at the end!
scanner.moveToThread(thread)
thread.start()
Der Fortschrittsbalken erst am Ende aktualisiert wird (meine Vermutung ist, dass alles auf dem gleichen Thread ausgeführt wird). Sollte es irrelevant sein, wenn ich das Signal vor oder nach dem Verschieben des Objekts, das das Objekt empfängt, an den Thread anschließe.
Sieht aus wie ekhumoro ist richtig (pyqt/qt scheint den Verbindungstyp nicht automatisch zu erkennen, es sei denn, Sie schmücken Ihre Slots explizit mit @pyqtSlot()). Ich möchte jedoch darauf hinweisen, dass die Zeile 'progress.setValue (100)' Thread ** unsich ist **, weil Sie von einem anderen Thread als dem Hauptthread auf ein Qt GUI-Objekt zugreifen. Der Rest Ihres geposteten Codes ist Thread-sicher in Bezug auf Qt GUI-Operationen –
@ three_pineapples. Es wäre interessant zu wissen, ob es hier einen PyQt-Bug gibt, oder ob es nur eine Besonderheit von PyQt ist, die sich mit Python-Callables verbindet. Ich weiß, dass eine Art Proxy-Objekt erstellt wird, wenn '@ pyqtSlot' nicht verwendet wird, aber genau, welche Konsequenzen dies für Warteschlangenverbindungen hat, weiß ich nicht. – ekhumoro
@ekhumoro Ich denke, es könnte ein PyQt4 Bug sein, oder zumindest ein Mangel, der behoben werden sollte. Es zeigt sicherlich nicht das gleiche Verhalten in PySide (PySide führt immer die "Scan" -Funktion im QThread aus, unabhängig davon, wo das Signal verbunden war oder wie der Slot dekoriert ist). Ich habe ein minimilistic Beispiel hier http://pastebin.com/SqP3WM1z gemacht, das ausdruckt, in welchem Faden Sachen laufen. –