我有一個QDialog創建一個QThread來做一些工作,同時保持UI響應,基於這裏給出的結構:How To Really, Truly Use QThreads; The Full Explanation。但是,如果拒絕()被調用(由於用戶按下取消或關閉對話框),而線程仍在運行,我得到一個錯誤:QDialog優雅地終止QThial拒絕()
QThread: Destroyed while thread is still running
我想什麼發生是循環的工作人員提早休息,然後在後臺做一些清理工作(例如清理一些隊列,發出信號)。我已經設法用我自己的「取消」功能來做到這一點,但是如何讓它與reject()(以及可以調用的所有方法)很好地發揮作用?我不希望對話框阻止等待清理 - 它應該繼續在後臺運行,然後優雅地退出。
請參閱下面的示例代碼,其中有問題。任何幫助將不勝感激。
#!/usr/bin/env python
from PyQt4 import QtCore, QtGui
import sys
import time
class Worker(QtCore.QObject):
def __init__(self):
QtCore.QObject.__init__(self)
def process(self):
# dummy worker process
for n in range(0, 10):
print 'process {}'.format(n)
time.sleep(0.5)
self.finished.emit()
finished = QtCore.pyqtSignal()
class Dialog(QtGui.QDialog):
def __init__(self):
QtGui.QDialog.__init__(self)
self.init_ui()
def init_ui(self):
self.layout = QtGui.QVBoxLayout(self)
self.btn_run = QtGui.QPushButton('Run', self)
self.layout.addWidget(self.btn_run)
self.btn_cancel = QtGui.QPushButton('Cancel', self)
self.layout.addWidget(self.btn_cancel)
QtCore.QObject.connect(self.btn_run, QtCore.SIGNAL('clicked()'), self.run)
QtCore.QObject.connect(self.btn_cancel, QtCore.SIGNAL('clicked()'), self.reject)
self.show()
self.raise_()
def run(self):
# start the worker thread
self.thread = QtCore.QThread()
self.worker = Worker()
self.worker.moveToThread(self.thread)
QtCore.QObject.connect(self.thread, QtCore.SIGNAL('started()'), self.worker.process)
QtCore.QObject.connect(self.worker, QtCore.SIGNAL('finished()'), self.thread.quit)
QtCore.QObject.connect(self.worker, QtCore.SIGNAL('finished()'), self.worker.deleteLater)
QtCore.QObject.connect(self.thread, QtCore.SIGNAL('finished()'), self.thread.deleteLater)
self.thread.start()
def main():
app = QtGui.QApplication(sys.argv)
dlg = Dialog()
ret = dlg.exec_()
if __name__ == '__main__':
main()
使用這種方法是有可能得到的主要應用程序等待的線程退出前清理?我將代碼作爲更大型應用程序(QGIS)中的插件運行。 – Snorfalorpagus
@snorfalorpagus:我更新了我的帖子。我認爲使用標誌是停止線程最安全的方法。 – nymk