从另一个 class 向主 class 发出信号

Emit a signal from another class to main class

当它在 Worker class - def 运行(self) 方法 中时,我得到了发射信号。一切 运行 都很好,while 循环能够循环并每 1 秒发出一个信号。然后标签会在接收到信号后更新。

我决定尝试将 while 循环放在另一个 class 命名循环 methodA 中。这是为了尝试查看发出的信号是否会被 MainWindow 接收。不幸的是,信号没有被接收到,然后程序就挂了。

我是否遗漏了阻止 while 循环发射信号被接收的任何步骤?请更改我的脚本,为我指明正确的方向。

谢谢。

import sys
import time
from PyQt5 import QtWidgets
from PyQt5.QtCore import QThread, pyqtSignal
from mydialog import Ui_mydialog


class Mainwindow(QtWidgets.QMainWindow, Ui_mydialog):

    def __init__(self, *args, obj=None, **kwargs):
        super(Mainwindow, self).__init__(*args, **kwargs)
        self.setupUi(self)

        self.thread = Worker()
        self.loop = loop()
        self.thread.sig.connect(self.updatelabel)

        self.mypushbutton.clicked.connect(self.mypushbuttonclicked)


    def mypushbuttonclicked(self):
        self.thread.start()

    def updatelabel(self, text):
        self.mylabel.setText(text)

class Worker(QThread):

    sig = pyqtSignal(str)

    def __init__(self, parent=None):
        super(Worker, self).__init__(parent)
        # self.count = 0
        self.loop = loop()

    def run(self):

        self.loop.methodA()

        ## Original code without being in class loop and method loopA
        # while True:
        #     time.sleep(1)
        #     self.count += 1
        #     if (self.count % 1 == 0):
        #         self.sig.emit(f"Timer: {self.count} s")

# Newly added class with method "methodA"
class loop(object):

    sig = pyqtSignal(str)

    def __init__(self):
        self.count = 0

    def methodA(self):

        while True:
            time.sleep(1)
            self.count += 1
            if (self.count % 1 == 0):
                self.sig.emit(f"Timer: {self.count} s")



app = QtWidgets.QApplication(sys.argv)
window = Mainwindow()
app.setStyle("Fusion")
window.show()
app.exec()

我遇到了类似的问题。 我按照以下方法解决了它:http://zetcode.com/gui/pyqt5/eventssignals/

想法是创建一个 class 来保存所有信号,并将相同的通信 class 作为参数传递给所有 classes。

所以你的代码可能会变成:

import sys
import time
from PyQt5 import QtWidgets
from PyQt5.QtCore import QThread, pyqtSignal, QObject
from mydialog import Ui_mydialog

class Communicate(QObject):
    sig = pyqtSignal(str) 

class Mainwindow(QtWidgets.QMainWindow, Ui_mydialog):

    def __init__(self, *args, obj=None, **kwargs):
        super(Mainwindow, self).__init__(*args, **kwargs)
        self.setupUi(self)
        self.communicate = Communicate()
        self.communicate.sig[str].connect(self.updatelabel)

        self.thread = Worker(communicate = self.communicate)
        #self.loop = loop() # this seems useless to me here
        
        self.mypushbutton.clicked.connect(self.mypushbuttonclicked)


    def mypushbuttonclicked(self):
        self.thread.start()

    def updatelabel(self, text):
        self.mylabel.setText(text)

class Worker(QThread):

    def __init__(self, parent=None, communicate=Communicate()):
        super(Worker, self).__init__(parent)
        self.communicate = communicate
        # self.count = 0
        self.loop = loop(communicate= self.communicate)

    def run(self):

        self.loop.methodA()

        ## Original code without being in class loop and method loopA
        # while True:
        #     time.sleep(1)
        #     self.count += 1
        #     if (self.count % 1 == 0):
        #         self.sig.emit(f"Timer: {self.count} s")

# Newly added class with method "methodA"
class loop(object):

    def __init__(self, communicate=Communicate()):
        self.count = 0
        self.communicate = communicate

    def methodA(self):

        while True:
            time.sleep(1)
            self.count += 1
            if (self.count % 1 == 0):
                self.communicate.sig.emit(f"Timer: {self.count} s")



app = QtWidgets.QApplication(sys.argv)
window = Mainwindow()
app.setStyle("Fusion")
window.show()
app.exec()

我还没有测试过这段代码,但我希望你已经明白了。