在以下代码中,我尝试处理stop()
。在这个可执行的例子中有三个按钮:第一个用于开始,第二个用于停止,第三个用于关闭。好吧,当我开始任务时,它的运行就像一个魅力。 但是当我希望while循环停止时,我点击停止按钮。现在,有一个问题:while循环不会停止。
您会看到,停止按钮会发出一个信号来调用TestTask()
上的from sys import argv
from PyQt4.QtCore import QObject, pyqtSignal, QThread, Qt, QMutex
from PyQt4.QtGui import QDialog, QApplication, QPushButton, \
QLineEdit, QFormLayout, QTextEdit
class TestTask(QObject):
def __init__(self, parent=None):
QObject.__init__(self, parent)
self._mutex = QMutex()
self._end_loop = True
def init_object(self):
while self._end_loop:
print "Sratus", self._end_loop
def stop(self):
self._mutex.lock()
self._end_loop = False
self._mutex.unlock()
class Form(QDialog):
stop_loop = pyqtSignal()
def __init__(self, parent=None):
QDialog.__init__(self, parent)
self.init_ui()
def init_ui(self):
self.pushButton_start_loop = QPushButton()
self.pushButton_start_loop.setText("Start Loop")
self.pushButton_stop_loop = QPushButton()
self.pushButton_stop_loop.setText("Stop Loop")
self.pushButton_close = QPushButton()
self.pushButton_close.setText("Close")
layout = QFormLayout()
layout.addWidget(self.pushButton_start_loop)
layout.addWidget(self.pushButton_stop_loop)
layout.addWidget(self.pushButton_close)
self.setLayout(layout)
self.setWindowTitle("Tes Window")
self.init_signal_slot_pushButton()
def start_task(self):
self.task_thread = QThread(self)
self.task_thread.work = TestTask()
self.task_thread.work.moveToThread(self.task_thread)
self.task_thread.started.connect(self.task_thread.work.init_object)
self.stop_loop.connect(self.task_thread.work.stop)
self.task_thread.start()
def stop_looping(self):
self.stop_loop.emit()
def init_signal_slot_pushButton(self):
self.pushButton_start_loop.clicked.connect(self.start_task)
self.pushButton_stop_loop.clicked.connect(self.stop_looping)
self.pushButton_close.clicked.connect(self.close)
app = QApplication(argv)
form = Form()
form.show()
app.exec_()
方法。
有什么问题?
npm update react-stepzilla
答案 0 :(得分:2)
stop_loop
信号被转换为事件并发送到信号接收器的线程。但是您的worker对象正在运行阻塞的while循环,这可以防止线程处理其事件队列中的任何挂起事件。因此,永远不会调用连接到stop_loop
信号的插槽。
要解决此问题,您可以在while循环中调用processEvents
以允许线程处理其挂起事件:
def init_object(self):
while self._end_loop:
QThread.sleep(1)
QApplication.processEvents()
print "Status", self._end_loop
或者,您可以直接调用工作人员的stop()
方法,而不是发出信号。严格来说,这不是线程安全的,但如果多个线程可以同时调用stop()
,那只会是一个问题。因此,更正确的方法是使用互斥锁来保护正在更改的值:
class TestTask(QObject):
def __init__(self, parent=None):
QObject.__init__(self, parent)
self._mutex = QtCore.QMutex()
self._end_loop = True
def stop(self):
self._mutex.lock()
self._end_loop = False
self._mutex.unlock()
现在直接从主线程调用stop()
是线程安全的。