2017-07-06 16 views
0

以下のコードは、QThreadを開始する単一のQDialogを作成します。 QDialogのcloseEvent()メソッドは、開始されたthreadを終了するように変更されました。QApplicationとそのQThreadsがすべて閉じられていることを確認する方法

threadが作業中のタスクを完了した場合にのみ終了する方法を教えてください。 quit()とそのterminate()メソッドでスレッドを停止する方法の違いは何ですか?メインアプリケーションウィンドウが閉じられる前に必ずthreadを終了する必要がありますか?なぜMac OS Xでは、メインダイアログが閉じられてスレッドが終了した後でも、プロセスがアクティビティモニタにリストされたままになるのはなぜですか?ここ

enter image description here

import threading 
import Queue as Queue 
import datetime 

global queue 
queue = Queue.Queue() 


class Thread(QThread): 
    def __init__(self, queue, parent): 
     QThread.__init__(self, parent) 
     self.queue = queue 

    def run(self): 
     while True: 
      task = queue.get() 
      output = task() 
      queue.task_done() 


def longToCalculate(): 
    for i in range(30000000): 
     i += i 
     if not i % 100000: 
      print '%s ...still calculating ' % datetime.datetime.now() 
    print 'calculation completed' 
    return i 


class Dialog(QDialog): 
    def __init__(self, parent=None): 
     super(Dialog, self).__init__(parent) 

    def closeEvent(self, event): 
     # self.thread.quit() 
     self.thread.terminate() 
     event.accept() 


class Dialog(QDialog): 
    def __init__(self, parent=None): 
     QDialog.__init__(self, parent) 
     self.queue = Queue.Queue() 
     self.thread = Thread(queue=self.queue, parent=self) 
     self.thread.start() 
     queue.put(longToCalculate) 

if __name__ == '__main__': 
    app = QApplication([]) 
    dialog = Dialog() 
    dialog.show() 
    qApp.exec_() 
+1

'terminate()'を呼び出すとスレッドが強制終了するという保証はありません(プラットフォームによって異なります)。スレッドがイベントループを実行していない場合、 'quit()'を呼び出すと何も起こりません。あなたの例はそうではありません。しかし、たとえそれがあったとしても、そのスレッドはrun()メソッドが返ると終了することができます。つまり、あなたの例では* never *(無限のwhileループのため)を意味します。また、長時間実行する関数を中断する方法を提供していないため、スレッドは完了するまで常に待機する必要があります。スレッドを殺すことが保証されている魔法の弾丸はありません - あなたは出口戦略を自分で提供しなければなりません。 – ekhumoro

答えて

0

キューを含まないサンプルコードです。

import os, sys 
import datetime 

from PyQt5.QtCore import * 
from PyQt5.QtGui import * 
from PyQt5.QtWidgets import * 

class Thread(QThread): 
    def __init__(self, parent): 

     QThread.__init__(self, parent) 

    def run(self): 
     self.longToCalculate() 

    def longToCalculate(self): 
     for i in range(30000000): 
      i += i 

      if (i % 1000000 == 0): 
       print('%s ...still calculating' % QDateTime.currentDateTime().toString()) 

     print('calculation completed') 
     return i 

class Dialog(QDialog): 
    def __init__(self, parent = None): 

     QDialog.__init__(self, parent) 

     self.thread = Thread(parent = self) 
     self.thread.start() 

     self.thread.finished.connect(self.threadComplete) 

    def threadComplete(self) : 
     QMessageBox.information(self, "Thread complete", "The thread has finished running. This program wil automatically close now.") 
     self.close() 

    def closeEvent(self, cEvent) : 

     if self.thread.isRunning() : 
      QMessageBox.information(self, "Thread running", "The thread is running. You cannot close this program.") 
      cEvent.ignore() 

     else : 
      cEvent.accept() 

if __name__ == '__main__': 

    app = QApplication(sys.argv) 

    dialog = Dialog() 
    dialog.show() 

    qApp.exec_() 
関連する問題