2017-05-16 2 views
1

J'utilise QThread pour effectuer des calculs dans un thread séparé. La commande Thread est lancée par un clic de bouton, qui lance la fonction StartMeasurement(). Le thread peut terminer le processus par lui-même (après avoir terminé les calculs) et émet le signal PyQT terminé. Ou le thread peut être arrêté par l'utilisateur par le clic stopBtn.Redémarrer QThread avec GUI

La fonction terminate() fonctionne, mais j'éprouve beaucoup de problèmes lorsque j'essaie de redémarrer le thread.

Est-il recommandé d'utiliser ici l'approche movetoThread()? Ou comment puis-je m'assurer que le thread est arrêté correctement pour permettre un redémarrage correct. (Moyens, à commencer nouveau!)

commence le measurment dans un thread: StartMeasurement()

def StartMeasurement(self):    

    self.thread = measure.CMeasurementThread(self.osziObj, self.genObj, self.measSetup) 

    self.thread.newSample.connect(self.plotNewSample) 
    self.thread.finished.connect(self.Done) 
    self.stopBtn.clicked.connect(self.thread.terminate) 
    self.stopBtn.clicked.connect(self.Stop) 

    self.thread.start() 

Répondre

1

Ce n'est pas un problème. La pratique générale lorsque vous travaillez avec QThread est de connecter son signal finished() à l'emplacement deleteLater() des objets qui ont été déplacés vers le thread séparé via moveToThread(). C'est fait afin de gérer correctement la mémoire lorsque vous détruisez votre thread car il est supposé que vous allez d'abord quitter le thread, puis détruire son instance. ;) Cela devrait vous dire que l'arrêt d'un thread n'a rien à voir avec la destruction de ces objets SAUF si vous avez établi la connexion que j'ai décrite ci-dessus.

Il est parfaitement possible de redémarrer un thread SI vous l'avez arrêté correctement en utilisant quit() et wait() pour attendre réellement jusqu'à ce que l'arrêt soit terminé.

Cependant, mon conseil est de ne pas le faire à moins que ce thread supplémentaire ait un impact énorme sur votre application pour une raison quelconque (hautement improbable avec les machines modernes).

au lieu de redémarrer le fil examiner les options suivantes:

  • mettre en œuvre un drapeau pause qui fait que la course de fil sans rien faire s'il est mis à true (je l'ai utilisé this exemple de mes nombreuses fois à démontrer un tel comportement (vérifiez la worker.cpp et la fonction doWork() en particulier) - il est en C++, mais il peut être porté à PyQt en peu de temps)
  • utilisation QRunnable - son conçu pour exécuter quelque chose, puis (à moins autoDelete est défini sur true) revenir au pool de threads. C'est vraiment bien si vous avez des tâches qui se produisent de temps en temps et que vous n'avez pas besoin d'un thread distinct. Si vous voulez utiliser les signaux et les créneaux horaires (pour obtenir le résultat du calcul effectué à l'intérieur du QRunnable::run() vous devrez d'abord hériter de QObject puis de QRunnable
  • terme d'utilisation (consultez le module Qt Concurrent)

I suggérons que vous lisiez d'abord le Example use cases pour les différentes technologies de filetage Qt.