Не посылается сигнал во второй поток через pyqtSignal - PyQt5

Не передаётся сигнал my_signal из основного класса App во второй класс (поток) ThreadForFunc.

В конечном результате должна запуститься функция test_func().

Вот весь код:

import sys
import time

from PyQt5 import QtCore, QtWidgets, QtGui
from PyQt5.QtWidgets import QWidget
from PyQt5.QtCore import QThread

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(800, 600)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.pushButton = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton.setGeometry(QtCore.QRect(224, 240, 291, 111))
        self.pushButton.setObjectName("pushButton")
        self.label = QtWidgets.QLabel(self.centralwidget)
        self.label.setGeometry(QtCore.QRect(190, 70, 351, 91))
        font = QtGui.QFont()
        font.setPointSize(26)
        self.label.setFont(font)
        self.label.setAlignment(QtCore.Qt.AlignCenter)
        self.label.setObjectName("label")
        MainWindow.setCentralWidget(self.centralwidget)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.pushButton.setText(_translate("MainWindow", "PushButton"))
        self.label.setText(_translate("MainWindow", "ПЕРВОЕ ОКНО"))



class ThreadForFunc(QThread): # второй поток
    def __init__(self):
        QThread.__init__(self)

    def __del__(self):
        self.wait()


    def run(self):
        print('run')
        self.app = App()
        self.app.my_signal.connect(self.test_func)

    def test_func(self):  # должна запуститься эта функция
        print('Работает!')
    

class App(QtWidgets.QMainWindow):
    my_signal = QtCore.pyqtSignal()

    def __init__(self):
        super(App, self).__init__()
        self.init_UI()


    def init_UI(self):
        self.main_ui = Ui_MainWindow()
        self.main_ui.setupUi(self)
        self.main_ui.pushButton.clicked.connect(self.ais_start) # запускаем нужную функцию по нажатию на кнопку


    def second_UI(self):
        self.second_ui = second_ui.Ui_MainWindow()
        self.second_ui.setupUi(self)
        self.second_ui.pushButton.clicked.connect(self.init_UI)


    def ais_start(self): 
        self.thread = ThreadForFunc()
        self.thread.start()
        time.sleep(0.1) # чтобы emit() не опередил connect()
        self.my_signal.emit()
        
        

if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)
    application = App()
    application.show()

    sys.exit(app.exec())

Спасибо за помощь новичкам вроде меня!


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

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

Я не знаю что вы задумали, но постарался реализовать то, что вы написали.

ВНИМАНИЕ !!!

Нельзя использовать time.sleep(1) в основном потоке - это блокирует интерфейс.

Нельзя обращаться из дополнительного потока к объектам основного потока !

import sys
#import time
from PyQt5 import QtCore, QtWidgets, QtGui
from PyQt5.QtWidgets import QWidget
from PyQt5.QtCore import QThread, QTimer


class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(800, 600)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.pushButton = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton.setGeometry(QtCore.QRect(224, 240, 291, 111))
        self.pushButton.setObjectName("pushButton")
        self.label = QtWidgets.QLabel(self.centralwidget)
        self.label.setGeometry(QtCore.QRect(190, 70, 351, 91))
        font = QtGui.QFont()
        font.setPointSize(26)
        self.label.setFont(font)
        self.label.setAlignment(QtCore.Qt.AlignCenter)
        self.label.setObjectName("label")
        MainWindow.setCentralWidget(self.centralwidget)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.pushButton.setText(_translate("MainWindow", "PushButton"))
        self.label.setText(_translate("MainWindow", "ПЕРВОЕ ОКНО"))


class ThreadForFunc(QThread):        
    def __init__(self):
        QThread.__init__(self)
        self.num = 1

    def run(self):
        print('Start run')
        while True:
            print(f'{self.num}')
            self.msleep(1000)
            self.num += 1
            
# Нельзя обращаться из дополнительного потока к объектам основного потока !           
#        self.app = App()
#        self.app.my_signal.connect(self.test_func)

    def test_func(self):        # должна запуститься эта функция
        print('Работает!')
        self.num = 0
    

class App(QtWidgets.QMainWindow, Ui_MainWindow):
    my_signal = QtCore.pyqtSignal()                                 # my_signal !!!

    def __init__(self):
        super(App, self).__init__()
        
        self.setupUi(self)
        
        # запускаем нужную функцию по нажатию на кнопку
        self.pushButton.clicked.connect(self.ais_start) 
        
        self.thread = ThreadForFunc()                               # +++ 
        self.my_signal.connect(self.thread.test_func)               # my_signal !!! +++


        ''' # ????
    def second_UI(self):
        self.second_ui = second_ui.Ui_MainWindow()
        self.second_ui.setupUi(self)
        self.second_ui.pushButton.clicked.connect(self.init_UI)
        '''

    def ais_start(self): 
#        self.thread = ThreadForFunc()
        self.thread.start()

# Нельзя использовать time.sleep(0.1) - это блокирует интерфейс.        
#        time.sleep(0.1)             # чтобы emit() не опередил connect()
#        self.my_signal.emit()

        #           через 3 сек.     vvvvvvvvvvvvvv <---- исполним 
        QTimer.singleShot(3000, self.my_signal.emit)                  # my_signal !!! 
        

if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)
    application = App()
    application.show()
    sys.exit(app.exec_())

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

→ Ссылка