我在 PyQt5 中有一個 GUI,它啟動一個從串行埠讀取的 QThread。當執行緒讀取所有資料時,它確實退出了,但是當我單擊停止按鈕時,我希望能夠停止它。我怎么做?下面是基本代碼:
# ...
class Worker(QObject):
finished = pyqtSignal()
progress = pyqtSignal(list)
def __init__(self):
QObject.__init__(self)
self._Reader = Reader()
self._Reader.progress = self.progress
self._Reader.finished = self.finished
def run(self):
self._Reader.read()
class Ui(QtWidgets.QMainWindow):
# ...
def startClicked(self):
self.thread = QThread()
self.worker = Worker()
self.worker.moveToThread(self.thread)
self.thread.started.connect(self.worker.run)
self.worker.finished.connect(self.thread.quit)
self.worker.finished.connect(self.worker.deleteLater)
self.worker.finished.connect(self.workerFinished)
self.thread.finished.connect(self.thread.deleteLater)
self.worker.progress.connect(self.reportProgress)
self.thread.start()
def stopClicked(self):
# How do I stop the thread?
pass
uj5u.com熱心網友回復:
管理執行緒時,您可以執行以下操作,如此處的檔案中所述:https : //doc.qt.io/qt-5/qthread.html
您可以通過呼叫 exit() 或 quit() 來停止執行緒。
https://doc.qt.io/qt-5/qthread.html#exit
出口:
告訴執行緒的事件回圈以回傳碼退出。
呼叫此函式后,執行緒離開事件回圈并從對 QEventLoop::exec() 的呼叫回傳。QEventLoop::exec() 函式回傳 returnCode。
按照慣例,returnCode 為 0 表示成功,任何非零值表示錯誤。
https://doc.qt.io/qt-5/qthread.html#quit
退出:
告訴執行緒的事件回圈以回傳碼 0(成功)退出。相當于呼叫 QThread::exit(0)。
如果執行緒沒有事件回圈,則此函式不執行任何操作。
uj5u.com熱心網友回復:
我假設您在某個資料處理回圈中讀取資料。如果這個假設是錯誤的,那么下面的當然是無效的。
您不能quit()直接從主執行緒呼叫輔助執行緒,并期望輔助執行緒會立即處理它并退出執行緒。原因是執行緒在資料處理回圈中忙于讀取資料。所以需要在輔助執行緒中中斷資料處理回圈,讓事件回圈空閑。
(順便說一句,不要混淆資料處理回圈和事件回圈。資料處理回圈是你自己寫的從埠讀取資料的回圈。事件回圈是Qt在你呼叫后自動創建的回圈QThread::start(),它正在處理輔助執行緒中的事件、信號和槽。)
為了打破資料處理回圈,你需要做兩件事:
QThread::requestInterruption()從主執行緒呼叫作為對按下某些“中止”按鈕的回應(不要擔心執行緒安全,請求中斷是執行緒安全/原子的)- 在輔助執行緒的回圈中,您需要定期檢查
QThread::isInterruptionRequested(),如果回傳true,則break回圈并發出工人的finished()信號
一旦您從輔助執行緒中的回圈中斷,輔助執行緒中的事件回圈就可用于處理從主執行緒發送的信號。
我可以在您的代碼中看到 worker 的finished()信號連接到QThread::quit(). 因此,finished()從輔助執行緒發出(從資料處理回圈中斷后)將呼叫執行緒quit(),該執行緒將由輔助執行緒的事件回圈(現在處于空閑狀態)處理,它將退出事件回圈,隨后退出執行緒,如果您有正確連接所有內容,它將洗掉作業執行緒和執行緒。(雖然我沒有檢查你代碼的這部分)
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/317134.html
上一篇:AppleScript-當從應用程式(而不是從Finder)提示時,如何設定finder視窗提示的目標/路徑?
下一篇:背景虛化的方法
