Comment arrêter un QThread partir de l'interface graphique
C'est une question de suivi à un précédent j'ai posté plus tôt.
Le problème est de savoir comment stop (arrêter|quitter|quitter) un QThread partir de l'interface graphique lors de l'utilisation de la méthode recommandée de ne PAS sous-classement Qthread, mais plutôt vreating un QObject, puis en les déplaçant vers un QThread. Ci-dessous, si un exemple de travail. Je peux commencer le GUI et le Qthread et je peux avoir la dernière mise à jour de l'interface graphique. Cependant, je ne peux pas l'arrêter. J'ai essayé plusieurs méthodes pour qthread (quit(), exit(), et même de le terminer()) en vain.
Aider grandement apprécié.
Voici le code complet:
import time, sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *
class SimulRunner(QObject):
'Object managing the simulation'
stepIncreased = pyqtSignal(int, name = 'stepIncreased')
def __init__(self):
super(SimulRunner, self).__init__()
self._step = 0
self._isRunning = True
self._maxSteps = 20
def longRunning(self):
while self._step < self._maxSteps and self._isRunning == True:
self._step += 1
self.stepIncreased.emit(self._step)
time.sleep(0.1)
def stop(self):
self._isRunning = False
class SimulationUi(QDialog):
'PyQt interface'
def __init__(self):
super(SimulationUi, self).__init__()
self.goButton = QPushButton('Go')
self.stopButton = QPushButton('Stop')
self.currentStep = QSpinBox()
self.layout = QHBoxLayout()
self.layout.addWidget(self.goButton)
self.layout.addWidget(self.stopButton)
self.layout.addWidget(self.currentStep)
self.setLayout(self.layout)
self.simulRunner = SimulRunner()
self.simulThread = QThread()
self.simulRunner.moveToThread(self.simulThread)
self.simulRunner.stepIncreased.connect(self.currentStep.setValue)
self.stopButton.clicked.connect(simulThread.qui) # also tried exit() and terminate()
# also tried the following (didn't work)
# self.stopButton.clicked.connect(self.simulRunner.stop)
self.goButton.clicked.connect(self.simulThread.start)
self.simulThread.started.connect(self.simulRunner.longRunning)
self.simulRunner.stepIncreased.connect(self.current.step.setValue)
if __name__ == '__main__':
app = QApplication(sys.argv)
simul = SimulationUi()
simul.show()
sys.exit(app.exec_())
[qt-project.org/doc/qt-4.8/qthread.html#quit] vraiment devrait être la voie à suivre ici... essayer de nouveau, peut-être avec quelques rudimentaire de débogage autour de l'appel de la fonction?
OriginalL'auteur stefano | 2013-04-26
Vous devez vous connecter pour publier un commentaire.
Je sais que je suis depuis longtemps mais je viens de tombé sur le même problème.
J'ai été aussi à la recherche d'un moyen approprié de le faire. Enfin, c'était facile. Lorsque vous quittez l'application, la tâche doit être arrêté et le fil doit être arrêté en appelant sa méthode de quitter. Voir stop_thread méthode sur le fond. Et vous avez besoin d'attendre pour le fil à la fin. Sinon, vous aurez une QThread: Détruit tandis que le thread est toujours en cours d'exécution " message à la sortie.
(J'ai aussi changé mon code pour utiliser pyside)
OriginalL'auteur maggie
J'ai découvert que ma question d'origine était en fait deux questions en une: dans le but d'arrêter un thread secondaire de la principale, vous avez besoin de deux choses:
Être en mesure de communiquer à partir du thread principal bas le thread secondaire
Envoyer le bon signal pour arrêter le fil
Je n'ai pas été en mesure de résoudre (2), mais j'ai trouvé comment le résoudre (1), qui m'a donné une solution à mon problème initial. Au lieu de l'arrêt de la fil, je peux arrêter le thread traitement (le
longRunning()
méthode)Le problème est que, d'un thread secondaire ne peut répondre aux signaux si elle gère sa propre boucle d'événements. Régulièrement Qthread (qui est ce que mon code utilisé) ne fonctionne pas. Il est assez facile, même si, à la sous-classe QThread à cet effet:
et utilisé
self.simulThread = MyThread()
dans mon code au lieu de l'originalself.simulThread = Qthread()
.Cela garantit que le thread secondaire exécute une boucle d'événements. Ce n'était pas assez, cependant. Le
longRunning()
méthode doit avoir une chance de participer à des processus de l'événement à venir vers le bas à partir du thread principal. Avec l'aide de cette SORTE de réponse j'ai compris que le simple ajout d'unQApplication.processEvent()
dans lelongRunning()
méthode a donné le thread secondaire à une telle chance. Je peux maintenant arrêter la traitement menées dans le thread secondaire, même si je n'ai pas compris comment arrêter le fil lui-même.Pour conclure. Mon longRunning méthode ressemble maintenant à ceci:
et mon thread GUI a ces trois lignes que de faire le travail (en plus de la sous-classe QThread énumérés ci-dessus):
Commentaires sont les bienvenus!
OriginalL'auteur stefano