Сбой PySide2 Qthread - PullRequest
       49

Сбой PySide2 Qthread

2 голосов
/ 01 ноября 2019

Я хочу использовать PySide2 Qtcore.Qthread из-за Qtcore.Signal, но я получаю эту ошибку: процесс завершен с кодом выхода -1073740791

from PySide2.QtCore import 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')

Thread().start()

ожидаем, что эти отпечатки, но у меня есть этоошибка:

Процесс завершен с кодом выхода -1073740791

Обновление:

, так почему этот код также вызывает ту же ошибку?

class Thread(QThread):
    done = Signal()

    def __init__(self):
        super(Thread, self).__init__()

    def run(self):
        print('task started')
        k = 0
        for i in range(10000):
            for j in range(5000):
                k += 1
        print('task finished')
        self.done.emit()

class Widget(QtWidgets.QWidget):
    def __init__(self):
        super(Widget, self).__init__()
        btn = QtWidgets.QPushButton('test', parent=self)
        btn.clicked.connect(self.clicked)
        btn.show()

    def clicked(self):
        t = Thread()
        t.done.connect(self.done)
        t.start()

    def done(self):
        print('done')

app = QtWidgets.QApplication()
window = Widget()
window.show()
sys.exit(app.exec_())

Ответы [ 2 ]

2 голосов
/ 01 ноября 2019

Объяснение

Если вы запустите свой код в 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 варианта:

  • Makeатрибут класса "t"
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()
0 голосов
/ 01 ноября 2019

Я нашел решение, но не знаю, зачем мне это делать. поток должен быть частью класса.

self.t = Thread()
self.t.done.connect(self.done)
self.t.start()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...