如何解决关闭在QThread中运行循环的工作程序在PySide2中挂起,但在PyQt5中挂起
我正在尝试调试一个关闭PySide2(15.15.0)中的线程的问题。我终于意识到代码可以在PyQt5上正常运行,所以我怀疑这是一个错误,但是也许我错过了一些明显的事情?
我整理了一个简单的最小可重复示例(python example.py pyside
在PySide2中运行,或者python example.py pyqt
在PyQt5中运行):
import sys
# Choose Pyside2 or PyQt5 binding
args = sys.argv
if len(args) > 1 and (sys.argv[1] == "pyqt5" or sys.argv[1] == "pyqt"):
binding = "pyqt5"
else:
binding = "pyside2"
print("Loading {} binding".format(binding))
if binding == "pyside2":
from PySide2.QtCore import *
from PySide2.QtGui import *
from PySide2.QtWidgets import *
elif binding == "pyqt5":
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
Signal = pyqtSignal
Slot = pyqtSlot
class Worker(QObject):
started = Signal(int)
done = Signal(int)
def __init__(self,id=None):
super().__init__()
self.id = id
print("worker-{}: init".format(self.id))
# Work loop - run until stop called
@Slot()
def run(self):
self.running = True
self.started.emit(self.id)
while self.running:
print("worker-{}: running".format(self.id))
QThread.msleep(500)
print("worker-{}: done".format(self.id))
self.done.emit(self.id)
# Stop worker
@Slot()
def stop(self):
print("worker-{}: stopping".format(self.id))
self.running = False
# Main window with start and stop buttons
class MainWindow(QMainWindow):
def __init__(self,binding="None"):
super().__init__()
self.counter = 0
self.workers = []
# Create widgets and connect signals
lbl = QLabel(binding)
btn_start = QPushButton("Start")
btn_start.pressed.connect(self.start)
btn_stop = QPushButton("Stop")
btn_stop.pressed.connect(self.stop)
# Layout GUI and show
layout = QVBoxLayout()
layout.addWidget(lbl)
layout.addWidget(btn_start)
layout.addWidget(btn_stop)
w = QWidget()
w.setLayout(layout)
self.setCentralWidget(w)
self.show()
# Start a worker in a new thread
def start(self):
# Increment worker id
self.counter = self.counter + 1
# Create worker and thread + store reference
worker = Worker(self.counter)
thread = QThread()
worker.moveToThread(thread)
self.workers.append((worker,thread))
# Connect signals and start thread+worker
thread.started.connect(worker.run)
worker.started.connect(lambda id: print("main: worker-{} started".format(id)))
worker.done.connect(lambda id: print("main: worker-{} done".format(id)))
thread.start()
# Stop all workers
def stop(self):
for (worker,thread) in self.workers:
worker.stop()
thread.quit()
thread.wait()
self.workers = []
def main():
app = QApplication([])
window = MainWindow(binding=binding)
app.exec_()
if __name__ == "__main__":
main()
我可以通过在QApplication.processEvents()
之后轮询thread.quit()
来“解决”该问题,这可能有助于诊断问题:
# Stop all workers
def stop(self):
for (worker,thread) in self.workers:
worker.stop()
thread.quit()
while thread.isRunning():
QApplication.processEvents()
thread.wait()
self.workers = []
作为附加说明,在PySide2
感谢您的帮助!
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。