Seite 1 von 1

QThread: QThread::finished() blockiert QThread::terminated()

Verfasst: Sonntag 20. Februar 2011, 12:27
von root_tux_linux
Hi

Ich hab ein kleines Problem und zwar überlagert das "finished" Signal das "terminated" Signal des QThread.

Wenn ich nun auf Abort drücke, wird der Thread mit QThread::terminate() abgeschossen, aber das Signal finished() und terminated() ausgelöst, wobei das finished() Signal, terminated() überlagert und deshalb dann die Funktion self.onFinish() ausgelöst wird anstelle von self.onAbort().

Kann man das irgendwie zurecht biegen? :/


Btw. Wenn ich die Zeile "self.connect(self.thread, QtCore.SIGNAL('finished()'), self.onFinish)" auskommentiere funzt das terminated() Signal wie es sollte :/

Code: Alles auswählen

        # Signal and Slots for QThread
        self.connect(self.buttonBox.button(QtGui.QDialogButtonBox.Abort), QtCore.SIGNAL('clicked()'), self.thread.terminate)
        self.connect(self.thread, QtCore.SIGNAL('terminated()'), self.onAbort)
        self.connect(self.thread, QtCore.SIGNAL('finished()'),  self.onFinish)
        self.thread.dataWritten.connect(self.progressBar.setValue)
        self.thread.currentPass.connect(self.labelPasses.setText)
            
    def onAbort(self):
        self.progressBar.setValue(self.size)
        self.progressBar.setFormat('Aborted')

    def onFinish(self):
        self.progressBar.setValue(self.size)
        self.progressBar.setFormat('succsessfully completet')

class Thread(QtCore.QThread):
    dataWritten = QtCore.pyqtSignal(int)
    currentPass = QtCore.pyqtSignal(str)
    
    def __init__(self, algo, device,  size):
        QtCore.QThread.__init__(self)
        self.algo = algo
        self.device = device
        self.size  = size
      
    def run(self):
        stat = 0
        f = open(self.device,  'wb')
        
        for method in self.algo:
            if method == 'random':
                data = urandom(1000)
            else:
                data = method * 256
                
            for i in xrange(self.size): # not Python 3000 compatible (range)
                f.write(data)
                self.dataWritten.emit(i)
            f.seek(0)
            stat +=1
            self.currentPass.emit(str(stat)+'/'+str(len(self.algo))) 

        f.close()

Re: QThread: QThread::finished() blockiert QThread::terminat

Verfasst: Sonntag 20. Februar 2011, 13:45
von lunar
Das ".terminate()"-Signal „funzt“ auch, nur wird es wahrscheinlich vor ".finished()" ausgelöst, und im Slot zu ".finished()" werden die vorherigen Werte überschrieben. Du musst Dir in ".onAbort()" eben merken, dass der Thread gewaltsam abgebrochen wurde, und die Anweisungen in ".onFinish()" nur ausführen, wenn dem nicht so war.

Wenn Du die neue Syntax bereits zur Deklaration der Signale nutzt, dann kannst Du sie auch beim Verbinden nutzen (e.g. "self.thread.finished.connect(self.onFinish)").

Die Warnung in der Dokumentation von "QThread.terminate()" ist im Übrigen nicht zum Scherz da, von der Verwendung von ".terminate()" wird dringend abgeraten. Diese Funktion ist nicht dazu da, einen „Abbrechen“-Knopf zu implementieren.

Re: QThread: QThread::finished() blockiert QThread::terminat

Verfasst: Sonntag 20. Februar 2011, 14:44
von root_tux_linux
lunar hat geschrieben:Diese Funktion ist nicht dazu da, einen „Abbrechen“-Knopf zu implementieren.
Wie dann?

Wenn ich mit self.exec_() ne eigene Eventschleife aufbaue und dann mittels self.exit() den Thread von innen beenden will läuft der Sack weiter.

Re: QThread: QThread::finished() blockiert QThread::terminat

Verfasst: Sonntag 20. Februar 2011, 15:08
von lunar
Üblicherweise, indem Du regelmäßig auf eine Abbruchbedingung prüfst (Beispiel).

Zu Deinem Problem mit ".exec_()" und ".exit()" kann man ohne Quelltext nichts sagen.