У меня есть программа, которую я хочу при нажатии кнопки создать qthread и запустить некоторый набор кода. В конце я хочу, чтобы основной поток уничтожил рабочий поток.
Следующий код показывает одну из моих попыток. Из того, что я могу сказать, он создает поток только при первом нажатии кнопки, а при втором нажатии он уничтожает предыдущий поток и создает и запускает функцию work(). Если вы долго ждете между нажатиями кнопок, вы получаете вид, похожий на первый щелчок кнопки, что он не запускает функцию work(). Может ли кто-нибудь увидеть что-то, что я делаю неправильно. У меня есть более сложный пример, который я пытаюсь разбить на меньшую часть (Pyqt5 qthread + сигнал не работает + зависание графического интерфейса)
Код:
import time
import sys
from PyQt5.QtCore import QObject, QThread, pyqtSignal, pyqtSlot
from PyQt5.QtWidgets import QApplication, QPushButton, QTextEdit, QVBoxLayout, QWidget
class Worker(QObject):
"""
Must derive from QObject in order to emit signals, connect slots to other signals, and operate in a QThread.
"""
sigDone = pyqtSignal(int)
def __init__(self, id: int):
print("Here 11")
super().__init__()
print("Here 9")
self.__id = id
@pyqtSlot()
def work(self):
print("Here 10")
for count in range(20):
print("ID: " + str(self.__id) + ", Count: " + str(count))
time.sleep(0.1)
app.processEvents() # this could cause change to self.__abort
self.sigDone.emit(self.__id)
#Need a done signal.
class MyWidget(QWidget):
def __init__(self):
super().__init__()
print("Here 1")
self.setWindowTitle("Thread Example")
form_layout = QVBoxLayout()
self.setLayout(form_layout)
self.resize(400, 400)
print("Here 2")
self.btnStartWorker = QPushButton()
self.btnStartWorker.clicked.connect(self.start_worker)
self.btnStartWorker.setText("Start Worker")
form_layout.addWidget(self.btnStartWorker)
self.__threads = None
def start_worker(self):
print("Here 3")
worker = Worker(999)
thread = QThread()
print("Here 4")
self.__threads = []
self.__threads.append(thread)
print("Here 5")
worker.moveToThread(thread)
worker.sigDone.connect(self.workerDone)
print("Here 6")
thread.started.connect(worker.work)
print("Here 7")
thread.start()
print("Here 8")
@pyqtSlot(int)
def workerDone(self, threadNumber):
print("Here 12")
print("Thread " + str(threadNumber) + " is done.")
for thread in self.__threads:
thread.quit()
thread.wait()
print("Here 13")
if __name__ == "__main__":
app = QApplication([])
form = MyWidget()
form.show()
sys.exit(app.exec_())
Результаты нескольких нажатий кнопок:
E:\myCode\python\pyQt>python3 pyQtv6.py
Here 1
Here 2
Here 3
Here 11
Here 9
Here 4
Here 5
Here 6
Here 7
Here 8
Here 3
Here 11
Here 9
Here 4
QThread: Destroyed while thread is still running
Here 5
Here 6
Here 7
Here 8
Here 10
ID: 999, Count: 0
ID: 999, Count: 1
ID: 999, Count: 2
ID: 999, Count: 3
ID: 999, Count: 4
ID: 999, Count: 5
ID: 999, Count: 6
ID: 999, Count: 7
ID: 999, Count: 8
ID: 999, Count: 9
ID: 999, Count: 10
ID: 999, Count: 11
ID: 999, Count: 12
ID: 999, Count: 13
ID: 999, Count: 14
ID: 999, Count: 15
ID: 999, Count: 16
ID: 999, Count: 17
ID: 999, Count: 18
ID: 999, Count: 19
Here 12
Thread 999 is done.
Here 13
Here 3
Here 11
Here 9
Here 4
Here 5
Here 6
Here 7
Here 8
Here 3
Here 11
Here 9
Here 4
QThread: Destroyed while thread is still running
Here 5
Here 6
Here 7
Here 8