Почему не работает QTimer?

Кнопка btn - единственный виджет окна. Она привязана к методу new_thread, который создает новый поток.

Внутри потока есть метод func_1. Он должен три раза создать таймер, срабатывание которого должно привести к вызыву метода func_2. Почему-то код метода func_2 не выполняется. Пожалуйста, подскажите, что я делаю неправильно?

from PyQt5 import QtCore, QtWidgets

class MyThread(QtCore.QThread):
    def __init__(self, parent=None):
        QtCore.QThread.__init__(self, parent)

    def run(self):
        print('THREAD: run')
        self.func_1()

    def func_1(self):
        for i in range(0, 3):
            print('a')
            QtCore.QTimer.singleShot(150, self.func_2)

    def func_2(self):
        print('This doesn`t work :(')


class MyWindow(QtWidgets.QWidget):
    def __init__(self, parent = None):
        super().__init__(parent)

        box = QtWidgets.QHBoxLayout(self)

        btn = QtWidgets.QPushButton('Button', clicked = self.new_thread)
        box.addWidget(btn)

    def new_thread(self):
        self.mythread = MyThread()
        self.mythread.started.connect(self.on_started)
        self.mythread.finished.connect(self.on_finished)
        self.mythread.start()

    def on_started(self):
        print('THREAD: start')

    def on_finished(self):
        print('THREAD: finish')


if __name__ == '__main__':
    import sys
    app = QtWidgets.QApplication(sys.argv)
    window = MyWindow()
    window.setWindowTitle(' ')
    window.show()
    sys.exit(app.exec_())

UPD

from PyQt5 import QtCore, QtWidgets

class MyThread(QtCore.QThread):
    singlTimer = QtCore.pyqtSignal()

    def __init__(self, parent=None):
        QtCore.QThread.__init__(self, parent)

    def run(self):
        print('THREAD: run')
        self.func_1()

    def func_1(self):
        for i in range(0, 3):
            print('a')
            self.singlTimer.emit()

    def on_singlTimer(self):
        QtCore.QTimer.singleShot(150, self.func_2)

    def func_2(self):
        print('This doesn`t work :)')


class MyWindow(QtWidgets.QWidget):
    def __init__(self, parent = None):
        super().__init__(parent)

        box = QtWidgets.QHBoxLayout(self)

        btn = QtWidgets.QPushButton('Button', clicked = self.new_thread)
        box.addWidget(btn)

    def new_thread(self):
        self.mythread = MyThread()
        self.mythread.started.connect(self.on_started)
        self.mythread.finished.connect(self.on_finished)

        self.mythread.singlTimer.connect(self.mythread.on_singlTimer)

        self.mythread.start()

    def on_started(self):
        print('THREAD: start')

    def on_finished(self):
        print('THREAD: finish')


if __name__ == '__main__':
    import sys
    app = QtWidgets.QApplication(sys.argv)
    window = MyWindow()
    window.setWindowTitle(' ')
    window.show()
    sys.exit(app.exec_())

Ответы (1 шт):

Автор решения: S. Nick

Я думаю, что правильно сделать так:

from PyQt5 import QtCore, QtWidgets


class MyThread(QtCore.QThread):
    singlTimer = QtCore.pyqtSignal()                           # +++

    def __init__(self, parent=None):
        QtCore.QThread.__init__(self, parent)

    def run(self):
        print('THREAD: run')
        self.func_1()

    def func_1(self):
        for i in range(0, 3):
            print('a')
#            QtCore.QTimer.singleShot(150, self.func_2)
            self.singlTimer.emit()                             # +++

#    def func_2(self):
#        print('This doesn`t work :(')


class MyWindow(QtWidgets.QWidget):
    def __init__(self, parent = None):
        super().__init__(parent)

        box = QtWidgets.QHBoxLayout(self)

        btn = QtWidgets.QPushButton('Button', clicked = self.new_thread)
        box.addWidget(btn)

    def new_thread(self):
        self.mythread = MyThread()
        self.mythread.started.connect(self.on_started)
        self.mythread.finished.connect(self.on_finished)

        self.mythread.singlTimer.connect(self.on_singlTimer)            # +++

        self.mythread.start()

    def on_started(self):
        print('THREAD: start')

    def on_finished(self):
        print('THREAD: finish')

    def on_singlTimer(self):                                            # +++
        QtCore.QTimer.singleShot(150, self.func_2)

    def func_2(self):                                                   # +++
        print('This doesn`t work :)')


if __name__ == '__main__':
    import sys
    app = QtWidgets.QApplication(sys.argv)
    window = MyWindow()
    window.setWindowTitle(' ')
    window.show()
    sys.exit(app.exec_())

введите сюда описание изображения

→ Ссылка