我有pyqt接口,如果按下按钮,它将启动QThread。线程运行,完成后,我可以再次启动它,到目前为止没有问题。 现在,我添加了一个用于连续操作线程的复选框。如果选中了该复选框,则该按钮将保持按下状态,并且必须再次按下该按钮以停止线程。
显然,在停止之后,线程已正确完成(也使用isRunning()
方法进行了检查),但是如果我尝试在连续操作中再次启动它,则程序将崩溃。如果我改为在连续操作关闭的情况下重新启动它,则不会发生这种情况,但是在这种情况下,线程被启动和停止了两次。
如何解释这种行为?有没有办法使其按预期工作?
一个例子:
import sys
from PyQt5 import QtCore
import PyQt5.QtWidgets as QtW
from PyQt5.QtCore import QThread, pyqtSlot, pyqtSignal
import time
class MyWindow(QtW.QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle('MyWindow')
self._main = QtW.QWidget()
self.setCentralWidget(self._main)
self.button = QtW.QPushButton('Do it', self)
self.button.clicked.connect(self.do)
self.contincheck = QtW.QCheckBox("Continuous")
self.contincheck.clicked.connect(self.continuous_doing)
self.continuous = False
self.layout = QtW.QGridLayout(self._main)
self.layout.addWidget(self.button,0,0)
self.layout.addWidget(self.contincheck,1,0)
self.setLayout(self.layout)
self.show()
def continuous_doing(self):
if self.contincheck.isChecked():
self.button.setCheckable(True)
self.continuous = True
else:
self.button.setCheckable(False)
self.continuous = False
def do(self):
if self.button.isCheckable() and not self.button.isChecked():
self.button.setText('Do it')
self.button.clicked.connect(self.do)
self.contincheck.setEnabled(True)
else:
self.mythread = MyThread(self.continuous)
if self.button.isCheckable() and self.button.isChecked():
self.button.setText('Stop doing that')
self.contincheck.setDisabled(True)
self.button.clicked.connect(self.mythread.stop)
self.mythread.finished.connect(self.thread_finished)
self.mythread.signal.connect(self.done)
self.mythread.start()
@pyqtSlot(int)
def done(self, i):
print('done it', i)
@pyqtSlot()
def thread_finished(self):
print('thread finished')
class MyThread(QThread):
signal = pyqtSignal(int)
def __init__(self, continuous):
QThread.__init__(self)
self._stopped = True
self.continuous = continuous
self.i = 0
def __del__(self):
self.wait()
def stop(self):
self._stopped = True
def run(self):
self._stopped = False
while True:
self.signal.emit(self.i)
if self._stopped:
break
if self.continuous: time.sleep(2)
else: break
if __name__ == '__main__':
app = QtCore.QCoreApplication.instance()
if app is None:
app = QtW.QApplication(sys.argv)
mainGui = MyWindow()
mainGui.show()
app.aboutToQuit.connect(app.deleteLater)
app.exec_()
答案 0 :(得分:0)
问题在于您正在创建一个新线程,而不是重用现有线程,在下面的示例中,我向您展示了如何正确地进行操作:
Entries