将插槽连接到从类派生的所有对象的信号

2024-06-02 06:49:53 发布

您现在位置:Python中文网/ 问答频道 /正文

我刚开始使用PyQt5,非常感谢您的帮助。我有一个小部件W,它响应来自某个C类的所有对象的信息。小部件W只能由C类的对象更新,在更新过程中,它必须知道是哪个特定对象触发了它

问题是C类对象可能会在整个程序过程中继续创建。是否可以将信号/插槽范例应用于此问题

到目前为止,我的想法是:

  1. 理想情况下,我会将W上的插槽连接到C上的类变量。然而,Qt不允许信号作为类变量
  2. 我可以使用集合对象CO,这样任何新对象C都必须通过该对象的接口创建。然后我在这个物体上定义了一个信号,它将连接到W上的一个插槽。然而,这很难看,因为CO的存在只是为了解决这个问题
  3. 我可以将signal/slot范例放在一起,而只需将W的回调(slot)添加到C上的类变量中。然后,每当创建新对象C时,它就已经有了对回调的引用

Tags: 对象程序信息信号部件过程情况qt
1条回答
网友
1楼 · 发布于 2024-06-02 06:49:53

一种可能的解决方案是使用元类:

import sys

from PyQt5 import QtCore, QtWidgets


class MetaC(type(QtCore.QObject), type):
    def __call__(cls, *args, **kw):
        obj = super().__call__(*args, **kw)
        for receiver in cls.receivers:
            obj.signal.connect(receiver)
        return obj


class C(QtCore.QObject, metaclass=MetaC):
    signal = QtCore.pyqtSignal()
    receivers = []

    @classmethod
    def register(cls, slot):
        cls.receivers.append(slot)


class C1(C):
    def test(self):
        self.signal.emit()


class C2(C1):
    pass


class Widget(QtWidgets.QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)
        C.register(self.foo)

    def foo(self):
        print("foo")


if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    w = Widget()
    w.show()

    c1, c2 = C1(), C2()

    QtCore.QTimer.singleShot(1000, c1.test)
    QtCore.QTimer.singleShot(5 * 1000, c2.test)

    QtCore.QTimer.singleShot(6 * 1000, QtCore.QCoreApplication.quit)

    sys.exit(app.exec_())

相关问题 更多 >