Seite 1 von 1

QThread.run() startet nicht

Verfasst: Donnerstag 21. Juni 2018, 17:15
von Daniel612
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_())

Re: QThread.run() startet nicht

Verfasst: Donnerstag 21. Juni 2018, 18:00
von __deets__
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

Re: QThread.run() startet nicht

Verfasst: Freitag 22. Juni 2018, 10:21
von Daniel612
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.

Re: QThread.run() startet nicht

Verfasst: Freitag 22. Juni 2018, 10:44
von __deets__
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.