我对python和pyqt非常陌生。 当我使用Qdesigner和Qthread(非常有进程使用selenium) 我意识到我需要停止btn。 所以我查了两天。但是还没有得到解决。 我发现并尝试的是 将stop btn连接到这个插槽
@pyqtSlot()
def end_thread(self):
self.WorkerA_1.stop()
并将其放入WorkerA_1 Qthread脚本
def stop(self):
chromedriver = "C:/codes/Webdriver/chromedriver"
driver = webdriver.Chrome(chromedriver)
driver.quit()
self.terminate()
它似乎终止了WorkerA_1,并关闭了驱动程序。 但问题是, 对于问题1,我尝试创建新的Qthread来停止冻结GUI。 像这样,
def run(self):
chromedriver = "C:/codes/Webdriver/chromedriver"
webdriver.Chrome(chromedriver).quit()
self.WorkerA_1.stop()
正如您所看到的,我对python很陌生。self.WorkerA_1.stop()这个不行。 它确实终止了WorkerA_1,但也打开了另一个驱动程序。 给我看看错误信息。 我相信从A_thread向B_thread发送信号是另一件需要研究的事情。 不管怎样,我想学的是 如果你知道什么可能对我有帮助的话,请告诉我 问题来源StackOverflow 地址:/questions/59379270/pyqt5-qthread-how-to-stop-or-terminate-by-button-click
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。
在PyQt中,管理线程的终止和同步是一个常见的挑战,特别是当你需要从主线程控制工作线程的行为时。根据你的描述,你想要实现的是通过点击按钮来停止一个正在运行的QThread,该线程中可能包含使用Selenium进行网页操作的任务。这里有几个关键点需要注意:
不要直接调用self.terminate()
:虽然这确实可以结束线程,但它是不安全的,可能导致资源泄露或程序崩溃。Qt推荐使用更优雅的方式来停止线程中的任务。
使用信号与槽机制:这是Qt框架处理线程间通信的标准方式。你需要定义一个自定义信号,在需要停止线程时发射这个信号,并在工作线程类中连接一个槽函数来响应这个信号,执行清理和退出逻辑。
正确地停止Selenium驱动:确保在工作线程中正确地关闭WebDriver实例,而不是在尝试停止线程的方法中重新创建一个新的实例。
下面是一个简化的示例,展示了如何通过信号和槽来优雅地停止一个包含Selenium任务的QThread:
from PyQt5.QtCore import QThread, pyqtSignal
from selenium import webdriver
class WorkerA(QThread):
stop_signal = pyqtSignal() # 自定义信号用于通知线程停止
def __init__(self, chromedriver_path):
super().__init__()
self.chromedriver_path = chromedriver_path
self.driver = None
def run(self):
self.driver = webdriver.Chrome(self.chromedriver_path)
# 这里是你的Selenium任务...
# 示例:等待某个条件退出或循环检查stop_signal状态
while not self.stop_signal.is Emitting():
# 执行任务...
pass
if self.driver:
self.driver.quit()
def stop(self):
self.stop_signal.emit() # 发射停止信号
from PyQt5.QtWidgets import QApplication, QPushButton, QVBoxLayout, QWidget
from PyQt5.QtCore import pyqtSlot
class MainWindow(QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.button_stop = QPushButton('Stop Thread', self)
self.button_stop.clicked.connect(self.end_thread)
layout = QVBoxLayout()
layout.addWidget(self.button_stop)
self.setLayout(layout)
self.workerA_1 = WorkerA("C:/codes/Webdriver/chromedriver")
self.workerA_1.stop_signal.connect(self.workerA_1.quit) # 连接停止信号到线程的quit方法
self.workerA_1.finished.connect(self.workerA_1.deleteLater) # 线程结束后删除对象
@pyqtSlot()
def end_thread(self):
self.workerA_1.stop() # 调用工作线程的stop方法以发出停止信号
if __name__ == '__main__':
app = QApplication([])
window = MainWindow()
window.show()
app.exec_()
在这个例子中,我们没有直接在stop
方法中调用terminate
或quit
,而是定义了一个自定义信号stop_signal
,当用户点击“Stop Thread”按钮时,通过end_thread
槽函数发射这个信号。工作线程内部监听这个信号,并在收到信号后开始清理工作并自然结束。这样可以确保线程安全、有序地停止,同时避免了资源泄露的问题。