我需要安全地中斷/停止執行緒,并且我正在嘗試使用 requestInterrupt() 來安全停止。我一直在搜索谷歌和stackoverflow,但似乎我根本無法讓它停止執行緒。它沒有產生任何錯誤,就像我從未提出過請求一樣繼續前進。
isInterruptRequested() 根本沒有改變。請求中斷時它應該為 True,但它始終為 false。
我的代碼的 MRE:
import sys
from time import sleep
from pathlib import Path
#PyQt5 Imports
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(343, 362)
self.centralwidget = QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.gridLayoutWidget = QWidget(self.centralwidget)
self.gridLayoutWidget.setGeometry(QRect(20, 20, 301, 281))
self.gridLayoutWidget.setObjectName("gridLayoutWidget")
self.gridLayout = QGridLayout(self.gridLayoutWidget)
self.gridLayout.setContentsMargins(0, 0, 0, 0)
self.gridLayout.setObjectName("gridLayout")
self.stopSearch = QPushButton(self.gridLayoutWidget)
self.stopSearch.setEnabled(False)
self.stopSearch.setObjectName("stopSearch")
self.gridLayout.addWidget(self.stopSearch, 1, 1, 1, 1)
self.startSearch = QPushButton(self.gridLayoutWidget)
self.startSearch.setObjectName("startSearch")
self.gridLayout.addWidget(self.startSearch, 1, 0, 1, 1)
self.textEdit = QTextEdit(self.gridLayoutWidget)
self.textEdit.viewport().setProperty("cursor", QCursor(Qt.ForbiddenCursor))
self.textEdit.setAutoFormatting(QTextEdit.AutoBulletList)
self.textEdit.setUndoRedoEnabled(False)
self.textEdit.setReadOnly(True)
self.textEdit.setAcceptRichText(False)
self.textEdit.setObjectName("textEdit")
self.gridLayout.addWidget(self.textEdit, 0, 0, 1, 2)
MainWindow.setCentralWidget(self.centralwidget)
self.retranslateUi(MainWindow)
QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "Test Window"))
self.stopSearch.setText(_translate("MainWindow", "Stop Task"))
self.startSearch.setText(_translate("MainWindow", "Start Task"))
class contactPuller(QMainWindow, Ui_MainWindow):
def __init__(self):
super(contactPuller, self).__init__()
self.setupUi(self)
self.thread = QThread()
self.worker = searchWorker()
self.worker.moveToThread(self.thread)
self._connectActions()
def _connectActions(self):
self.startSearch.clicked.connect(self.searchStart)
self.stopSearch.clicked.connect(self.searchStop)
self.thread.started.connect(self.worker.run)
self.worker.finished.connect(self.thread.quit)
self.worker.finished.connect(self.worker.deleteLater)
self.thread.finished.connect(self.thread.deleteLater)
self.worker.progress.connect(self.reportProgress)
self.thread.finished.connect(lambda: self.startSearch.setEnabled(True))
def searchStart(self):
self.textEdit.clear()
self.startSearch.setEnabled(False)
self.stopSearch.setEnabled(True)
self.thread.start()
def searchStop(self):
self.textEdit.append('searchStop called')
self.startSearch.setEnabled(True)
self.stopSearch.setEnabled(False)
self.worker.requestInterruption()
self.thread.requestInterruption()
def reportProgress(self, text):
self.textEdit.append(text)
class searchWorker(QThread):
finished = pyqtSignal()
progress = pyqtSignal(str)
def __init__(self):
super(QThread, self).__init__()
def save(self):
self.progress.emit("Save Call")
def _terminate(self):
self.progress.emit("_terminate call")
def run(self):
while True:
sleep(2)
self.progress.emit(f'Interrupt reqested: {self.isInterruptionRequested()}')
print(f'Interrupt reqested: {self.isInterruptionRequested()}')
if self.isInterruptionRequested():
self.browser.quit()
self.save()
self.thread.stop()
self.thread.wait()
self.progress.emit('Stop Call')
if __name__ == "__main__":
app = QApplication([])
app.setStyle('Fusion')
cntctChkr = contactPuller()
cntctChkr.show()
sys.exit(app.exec())
編輯:將截斷的片段更改為“作業”示例
uj5u.com熱心網友回復:
您是 QThread 的子類,但您并沒有像這樣使用它,只是作為一個簡單的 QObject。
如果呼叫它requestInterruption()的執行緒未運行(或已完成),則忽略任何呼叫。
當您run從另一個執行緒運行該函式時,您并沒有運行該worker執行緒。
解決方案很簡單:不要使用另一個 QThread,使用你已有的。
class ContactPuller(QMainWindow, Ui_MainWindow):
def __init__(self):
super().__init__()
self.setupUi(self)
self.worker = SearchWorker()
self._connectActions()
def _connectActions(self):
self.startSearch.clicked.connect(self.searchStart)
self.stopSearch.clicked.connect(self.searchStop)
self.worker.progress.connect(self.reportProgress)
self.worker.finished.connect(self.workerFinished)
def searchStart(self):
self.textEdit.clear()
self.startSearch.setEnabled(False)
self.stopSearch.setEnabled(True)
self.worker.start()
def searchStop(self):
self.textEdit.append('searchStop called')
self.stopSearch.setEnabled(False)
self.worker.requestInterruption()
def reportProgress(self, text):
self.textEdit.append(text)
def workerFinished(self):
self.startSearch.setEnabled(True)
class SearchWorker(QThread):
progress = pyqtSignal(str)
def __init__(self):
super().__init__()
def save(self):
self.progress.emit("Save Call")
def _terminate(self):
self.progress.emit("_terminate call")
def run(self):
while True:
sleep(2)
interrupt = self.isInterruptionRequested()
self.progress.emit(f'Interrupt requested: {interrupt}')
print(f'Interrupt requested: {interrupt}')
if interrupt:
self.save()
self.progress.emit('Stop Call')
break
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/496628.html
