The code below creates a single QDialog
which starts a QThread
that gets a function that is long to calculate. QDialog's closeEvent()
method was modified to terminate the thread
that was started.
How to make sure the thread
is terminated only if it completed a task it was working on? What is the difference between stopping a thread with its quit()
and its terminate()
method? Should the thread
always be terminated before the main application window is closed? Why on Mac OS X the Python
process remains to be listed in Activity Monitor even after the main dialog is closed and the thread is terminated?
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_()
Here is a sample code which does not include Queue.
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_()
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments