Объяснение
Если вы запустите свой код в CMD / терминале, вы получите следующую ошибку:
QThread: Destroyed while thread is still running
Aborted (core dumped)
И ошибка вызвана тем, что поток уничтожен, пока он ещеработает, так как это локальная переменная, с другой стороны, QThread нуждается в цикле событий для запуска
Solution
import sys
from PySide2.QtCore import QCoreApplication, QThread
class Thread(QThread):
def run(self):
print("task started")
k = 0
for i in range(10000):
for j in range(5000):
k += 1
print("task finished")
if __name__ == "__main__":
# create event loop
app = QCoreApplication(sys.argv)
th = Thread()
th.start()
th.finished.connect(QCoreApplication.quit)
sys.exit(app.exec_())
Обновление:
"t "- это локальная переменная, которая будет удалена после выполнения щелчка, вызывающего ту же проблему, что и исходный код, решение состоит в том, чтобы предотвратить ее немедленное уничтожение, и для этого есть 2 варианта:
def clicked(self):
self.t = Thread()
self.t.done.connect(self.done)
self.t.start()
- Хранить QThread в контейнере с более длинным жизненным циклом:
class Widget(QtWidgets.QWidget):
def __init__(self):
super(Widget, self).__init__()
btn = QtWidgets.QPushButton('test', parent=self)
btn.clicked.connect(self.clicked)
self.container = []
def clicked(self):
t = Thread()
t.done.connect(self.done)
t.start()
self.container.append(t)
# ...
- Passэто как родительский элемент для «себя», но для этого необходимо, чтобы поток позволял получать, поэтому вы должны реализовать это в конструкторе:
class Thread(QThread):
done = Signal()
def __init__(self, parent=None):
super(Thread, self).__init__(parent)
# ...
def clicked(self):
t = Thread(self)
t.done.connect(self.done)
t.start()