У меня есть интерфейс 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_()