В следующем коде я стараюсь иметь дело с QThread
. В этом исполняемом примере есть три кнопки: первая для начала, вторая для остановки и третья для закрытия. Ну, когда я начинаю задание, он работает как шарм. BUT Когда я хочу, чтобы цикл while остановился, я нажимаю кнопку остановки. И теперь возникает проблема: цикл while не останавливается.PyQt: Как бороться с QThread?
Вы видите, кнопка останова выдает сигнал для вызова метода stop()
на 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_()
Кажется, что идия с QMutex() - класс не работает. Я обновил свой код. – Sophus
@Sophus. Он работает, но, как я сказал в своем ответе, вам нужно напрямую вызвать 'stop()'. Поэтому в 'stop_looping' замените emit на' self.task_thread.work.stop() '. Тогда сигнал 'stop_loop' вообще не нужен. – ekhumoro
@ ekhumoro: Вы были правы. Он работает. Спасибо. Не отменяется ли инкапсуляция данных, когда я вызываю метод напрямую? – Sophus