Seite 1 von 1

Gui Crash

Verfasst: Montag 21. Juni 2010, 07:57
von honk0190
Hallo zusammen,

ich habe ein Problem bei dem handling von QThread. und zwar stürzt mir manchmal die Gui einfach ab und bekomme den Fehler:
QObject::connect: Cannot queue arguments of type 'QTextCursor'
(Make sure 'QTextCursor' is registered using qRegisterMetaType().)

Hintergrund:
ich starte eine oberfläche und in der soll mit einem Thread etwas geschrieben werden.

Hier der Code:

Code: Alles auswählen

class MyGuiThread(QtCore.QThread):
    def __init__(self, dieGui,  derWorker):
        QtCore.QThread.__init__(self)
        self.darfLaufen=False
        self.dieGui= dieGui
        self.derWorker= derWorker

        
    def startStop(self):
        if self.darfLaufen:
            self.darfLaufen = False
            print "Ich halte MyGuiThread an"
            print "Ich halte MyWorkerThread an"
            #self.derWorker.killAll()
        else:
            self.darfLaufen=True
            print "Ich starte MyGuiThread"
            print "Ich starte MyWorkerThread"
            self.start()
            
    def run(self):

        n = 0
        step = 1
        while self.darfLaufen:
            n += step
            print n, "oder beliebige GUI Akionen, zb knopf aendern"
            # dazu muesste das Threadf Object das GUI Object erhalten
            # hier dann die aenderung an der gui, zb die werte gelesen und anzeigen o.ae.
            #self.derWorker.doChange()

            
            self.dieGui.area1.appendPlainText(str(n) +"\n")
            self.dieGui.area3.appendPlainText(str(n)+'\n')
            self.dieGui.area2.appendPlainText(str(n)+'\n')
            time.sleep(1)
in der main, rufe ich dann nur noch

Code: Alles auswählen

self.connect(self.uiRef.set, QtCore.SIGNAL("clicked()"), self.guithread.startStop)
auf und dann kommt der fehler.

Re: Gui Crash

Verfasst: Montag 21. Juni 2010, 19:24
von DaMutz
das Problem ist, dass du von einem Thread auf die GUI zugreifst. Dies hat Qt nicht gerne.

Code: Alles auswählen

self.dieGui.area1.appendPlainText(str(n) +"\n")
Sende stattdessen ein Signal aus mit dem Text, der die View empfängt und darstellt.

Re: Gui Crash

Verfasst: Mittwoch 23. Juni 2010, 13:09
von honk0190
und wie sende ich ein signal mit dem text?

Re: Gui Crash

Verfasst: Mittwoch 23. Juni 2010, 13:30
von jerch
In etwa so:

Code: Alles auswählen

class MyGuiThread(QtCore.QThread):
    newText = QtCore.pyqtSignal(str)               # oder QString, hängt vom Gegenüber ab
    def __init__(self, dieGui,  derWorker):
...         
    def run(self):
        ...
        self.newText.emit('Text goes here')

Re: Gui Crash

Verfasst: Donnerstag 24. Juni 2010, 08:24
von franzf
Ein SIGNAL setzt voraus, dass es auch connected ist, was nicht immer die schönste Lösung ist.
Man kann auch "direkt" eine Methode aus einem anderen Thread aufrufen, die dann in der Gui etwas zeichnet: via QMetaObject ;)
Dein Aufruf könnte dann so ausschauen:

Code: Alles auswählen

QMetaObject.invokeMethod(self.dieGui.area1, "appendPlainText", Qt.QueuedConnection, Q_ARG(QString, str(n)))
Wichtig ist die "QueuedConnection", da diese im Gegensatz zur directConnection gequeued wird ;) Das Ding kann dann nämlich später aus dem Gui-Thread heraus aufgerufen werden - denn QMetaObject.invokeMethod() macht Aufrufe über das Event-System.

Re: Gui Crash

Verfasst: Donnerstag 24. Juni 2010, 16:15
von lunar
@franzf: Das ist nichts anderes als eine Signal-Slot-Verbindung „ausgeschrieben“. Eine Signal-Slot-Verbindung ist eigentlich immer die schönere und sinnvollere Lösung, weil sie zusätzlich zur Thread-Sicherheit auch noch die Komponenten entkoppelt.