QThread.run() startet nicht

Python und das Qt-Toolkit, erstellen von GUIs mittels des Qt-Designers.
Antworten
Daniel612
User
Beiträge: 2
Registriert: Donnerstag 21. Juni 2018, 16:51

Hallo,

bei dem nachfolgenden Code wird die run() vom abgeleiteten Thread nur dann aufgerufen, wenn der Slot mit dem Signal "check_completed" verbunden ist. Wird der Thread nur gestartet, kommt es zum Abbruch und dem Fehlercode -1073740791 (0xC0000409). Die Methode run() wird dann gar nicht gestartet. Führe ich den Skript dagegen mit dem Debugger von PyCharm aus, läuft es ohne Probleme. Wo ist hier der Fehler?

Code: Alles auswählen

class RequestChecker(QtCore.QThread):
    check_completed = QtCore.pyqtSignal()

    def __init__(self, parent=None):
        super().__init__(parent)

    def run(self):
        print("Simuliere eine Überpüfung ...")
        self.sleep(3)
        self.check_completed.emit()


class MyWindow(QtWidgets.QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.check()

    def check(self):
        checker = RequestChecker()
        checker.start()
        #checker.check_completed.connect(lambda: print("Überprüfung beendet"))


if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    win = MyWindow()
    win.show()
    sys.exit(app.exec_())
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Du hälst keine Referenz auf dein Objekt. Es wird garbage collected. Und dann kracht es.

Wenn du eine connection machst, hält die das Objekt am Leben.

Pycharms Debugger macht das augenscheinlich auch.

Last but not least: du benutzt threads in qt falsch. Du musst in der Doku lesen, wie das richtig geht. Statt Ableitung muss man ein worker Objekt erzeugen & das dem Thread mit moveToThread geben. Sonst krachen deine Signale aus dem Thread & deine Software wird unstabil. Denn du brauchst queued connections. Das machen diese worker pattern für dich b
Daniel612
User
Beiträge: 2
Registriert: Donnerstag 21. Juni 2018, 16:51

Vielen Dank, funktioniert. Ich verstehe allerdings nicht wirklich, weshalb es zum Crash kommt. Beim Aufruf der start() existiert ja das Objekt noch. Oder schiebt QThread ein Ereignis in die Warteschlage zum Erstellen eines neuen Threads und wenn ein Thread erzeugt wird, keine Referenz mehr auf QThread existiert?

Danke für den Hinweis mit dem Worker. Ich lerne PyQt aktuell aus Büchern und Udemy-Kursen und dort wird nur meine Vorgehensweise demonstriert.
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Die Doku ist da sehr klar. Anschaut dir die mal an.

Und Nebenläufigkeit eines der schwierigsten Themen. Wenn du Start aufrufst wird vom OS ein neuer Thread angelegt. Das dauert aber ein paar Microsekunden bis der loslegt. In der Zeit ist der main thread schon weiter, und weil die Methode check beendet ist, ist auch der checker nicht mehr im scope. Wird also abgeräumt, und damit läuft der Thread ins leere.
Antworten