【问题标题】:Emit a signal from another class to main class从另一个类向主类发出信号
【发布时间】:2020-06-30 09:39:37
【问题描述】:

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

我决定尝试将 while 循环放在另一个名为循环的类 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()

【问题讨论】:

    标签: qthread


    【解决方案1】:

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

    这个想法是创建一个包含所有信号的类,并将相同的通信类作为参数传递给所有类。

    所以你的代码可能变成:

    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()
    

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

    【讨论】:

    • 我把这个 self.communicate[str].sig.connect(self.updatelabel) 改成了 self.communicate.sig.connect(self.updatelabel)
    • 嗯,我很乐意提供帮助。 "[str]" 告诉信号它有一个字符串类型的参数。我在程序中打错了,它应该看起来像“self.communicate.sig[str].connect(self.updatelabel)”。
    • 嗨 Abderrahim,我可以假设每当我需要从另一个类方法发出信号时,我都需要始终创建一个“通信”方法。通过这样做,我可以将 pyqtsignal 传递给其他外部类方法。
    • 我想知道为什么我不能将 "sig = pyqtSignal(str)" 放在类 loop(object) 下?为什么没有接收到发射信号?
    • @SKDN 因为这样做,您正在创建一个新信号( pyqtSignal() 是 pyqtSignal 类的构造函数),因此我们已经完成了 hack。您需要了解,要在同一信号上进行通信,您必须将同一信号传递给需要在它们之间进行通信的所有类。然后,您可以将在 Mainwindow._init()__ 上创建的“sig”递归地传递给所有类,这将起到同样的作用。我希望你已经明白了。
    猜你喜欢
    • 1970-01-01
    • 2017-02-17
    • 2013-02-17
    • 1970-01-01
    • 2019-07-31
    • 1970-01-01
    • 1970-01-01
    • 2021-12-24
    • 1970-01-01
    相关资源
    最近更新 更多