3 Stimmen

Wie sage ich einer Klassenmethode, dass sie warten soll, bis ein Signal von einer Klassenmethode eines QDialog gefangen wird?

Ich habe den folgenden Code:

class Functions(QObject):

    mysig = Signal(filename)

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

    def showDialog(self, filename):
        self.mysig.emit(filename)

    def grabResult(self):

        while not self.result:
            time.sleep(5)

        return result #this is the question

    def setResult(self, result):
        self.result = result

Der andere Teil des Codes hat das hier:

class Dialog(QDialog):

    anotherSig = Signal(str)
    fun = Functions()

    def __init__(self, parent=None, filename=filename):
        self.filename = filename
        #Hier wird basierend auf dem Filename-Parameter ein Bild angezeigt

    def okButtonClicked(self):
        text = self.lineedit.text()
        fun.setResult(text)
        #Habe auch das probiert:
        self.anotherSig.emit(text)

Die Functions() Klasse wird von einem Worker QThread aufgerufen (hier nicht gezeigt).

Meine Frage ist: wie sage ich meiner Functions Klasse, dass der Benutzer den Text eingegeben und die OK-Schaltfläche geklickt hat? Ich habe versucht, das anotherSig Signal zu verbinden, aber wenn ich das tue, beschwert sich Qt darüber, dass QPixmaps nicht sicher von einem anderen Thread aus gesetzt werden können, und es funktioniert nicht.

Die Methode, die ich hier verwende, "funktioniert", aber ich habe das Gefühl, dass sie nicht sehr zuverlässig ist. Außerdem funktioniert es nur, wenn alle relevanten Methoden in der Functions Klasse als @classmethod markiert sind - auf diese Weise funktioniert es aus irgendeinem Grund nicht. Die setResult wird aufgerufen (Ich habe eine print Anweisung hinzugefügt, um sicherzustellen), aber der grabResult zeigt immer noch self.result als None an.

0voto

tacaswell Punkte 79032

Dieser Code funktioniert nicht, weil der Aufruf von showDialog bei der Instanziierung eines Functions-Objekts geschieht, das ein Attribut des Objekts ist, das auf dem anderen Thread läuft. Ihr fun in Dialog, auf dem Sie das Ergebnis setzen, ist eine andere Instanziierung.

Um die Ergebnisse zurück zum ursprünglichen Functions-Objekt zu bewegen, denke ich, dass Sie anotherSig des Dialog-Objekts mit der setResult-Funktion auf dem Functions-Objekt verbinden müssen, auf das Sie die Ergebnisse zurückbekommen möchten.

Funktioniert so etwas (schwierig, dies ohne eine gute Menge Boilerplate zu testen).

class Functions(QObject):

    mysig = Signal(filename,Functions)

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

    def showDialog(self, filename):
        self.mysig.emit(filename,self)

    def grabResult(self):

        while not self.result:
            time.sleep(5)

        return result #das ist die Frage

    @QtCore.Slot(str)
    def setResult(self, result):
        self.result = result

def connection_fun(filename,fun):
    d = Dialog(filename)
    # was auch immer Sie hier tun
    d.anotherSig.connect(fun.setResult))

0voto

Die Verwendung von time.sleep führt dazu, dass Ihre Anwendung einfriert. Eine Methode, um Ihre Klasse warten zu lassen, ist die Verwendung von QEventLoop wie folgt:

loop = QEventLoop()
myDialog.mySignal.connect(loop.quit)
loop.exec_()

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X