簡體   English   中英

如何從 GUI 應用程序正確終止 QThread?

[英]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")

我有一個類似的問題並使用pyqtSignalspyqtSlots解決了它。 您可以在 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM