[英]How to properly terminate a QThread from a GUI application?
我嘗試在 QThread class 中使用self.terminate()
self.thread.terminate()
在 GUI class 中使用 self.thread.terminate()。我還嘗試在這兩種情況下self.wait()
。 但是,會發生兩種情況:
1) 線程根本沒有終止,GUI 凍結等待線程完成。 線程完成后,GUI 解凍,一切恢復正常。
2)線程確實終止了,但同時凍結了整個應用程序。
我也嘗試使用self.thread.exit()
。 沒有快樂。
為了進一步澄清,我正在嘗試在 GUI 中實現一個用戶中止按鈕,該按鈕將在任何時間點終止線程的執行。
提前致謝。
編輯:
這是run()
方法:
def run(self):
if self.create:
print "calling create f"
self.emit(SIGNAL("disableCreate(bool)"))
self.create(self.password, self.email)
self.stop()
self.emit(SIGNAL("finished(bool)"), self.completed)
def stop(self):
#Tried the following, one by one (and all together too, I was desperate):
self.terminate()
self.quit()
self.exit()
self.stopped = True
self.terminated = True
#Neither works
這是用於中止線程的 GUI 類方法:
def on_abort_clicked(self):
self.thread = threadmodule.Thread()
#Tried the following, also one by one and altogether:
self.thread.exit()
self.thread.wait()
self.thread.quit()
self.thread.terminate()
#Again, none work
從 QThread::terminate 的 Qt 文檔中:
警告:此功能很危險,不鼓勵使用。 線程可以在其代碼路徑中的任何一點終止。 修改數據時可以終止線程。 線程沒有機會自行清理,解鎖任何持有的互斥鎖等。簡而言之,只有在絕對必要時才使用此功能。
重新考慮您的線程策略可能是一個更好的主意,例如,您可以使用 QThread::quit() 來通知線程干凈地退出,而不是試圖讓線程以這種方式終止。 實際上,從線程內部調用 thread.exit() 應該這樣做,具體取決於您實現 run() 的方式。 如果你想分享你的線程運行方法的代碼,它可能會暗示它為什么不起作用。
這就是我所做的:
class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
stop_flag = 1
...
#=========500 ms class ===================
class Timer500msThread(QThread):
signal_500ms = pyqtSignal(str)
....
def timer500msProcess(self):
if MainWindow.stop_flag == 0 :
self.timer_500ms.stop()
#==========
#=========Main Window ===================
app = QtWidgets.QApplication(sys.argv)
window = MainWindow()
window.show()
app.exec()
MainWindow.stop_flag=0 #this sets the flag to 0 and when the next 500ms triggers the
#the thread ends
print("Program Ending")
我有一個類似的問題並使用pyqtSignals
和pyqtSlots
解決了它。 您可以在 MainWindow 類中創建一個pyqtSignal
並將aboutToQuit
-函數用於您的QApplication
實例。 然后將這個aboutToQuit
函數與另一個函數連接起來,后者會向單獨線程中的插槽發出信號。 然后,您可以在此線程中定義一個stop()
function,如果發出信號,它就會運行。 在這種情況下,線程不會在其工作期間終止。
主窗口:
class mainSignals(QObject):
isClosed = pyqtSignal()
class mainwindow(QMainWindow, Ui_MainWindow):
def __init__(self):
super(mainwindow, self).__init__()
self.mainSignal = mainSignals()
...
...
if __name__ = "__main__":
# This function runs if the application is closed.
# (app.aboutToQuit.connect(windowClose))
def windowClose():
window.mainSignal.isClosed.emit() # Emit the signal to the slot in (sepThread)
app = QApplication(sys.argv)
app.aboutToQuit.connect(windowClose)
window = mainwindow()
window.show()
sys.exit(app.exec())
分離線程:
class sepThread(QRunnable):
def __init__(self, parent):
super(sepThread,self).__init__()
self._parent = parent
self.mainOpen = True
self._parent.mainSignal.isClosed.connect(self.stopThread)
# If the signal was emitted by the Mainapplication
# the stopThread function runs and set the mainOpen-attribute to False
def stopThread(self):
self.mainOpen = False
def run(self):
while self.mainOpen == True:
# Do something in a loop while mainOpen-attribute is True
...
...
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.