python - 将插槽连接到来自类派生的所有对象的信号
问题描述
我刚开始使用 PyQt5,希望能得到一些帮助。我有一个小部件 W,它响应来自某个类 C 派生的所有对象的信息。小部件 W 只能由 C 类的对象更新,并且在更新期间,它必须知道哪个特定对象触发了它。
问题是 C 类的对象可能会在整个程序过程中继续创建。是否可以将信号/插槽范式应用于此问题?
到目前为止我的想法:
- 理想情况下,我会将 W 上的插槽连接到 C 上的类变量。但是,Qt 不允许信号作为类变量。
- 我可以使用集合对象 CO,这样任何新对象 C 都必须通过该对象的接口创建。然后我在这个对象上定义了一个信号,它将连接到 W 上的一个插槽。然而,这很丑,因为 CO 的存在只是为了解决这个问题。
- 我可以将信号/插槽范式全部删除,而只需将 W 的回调(插槽)添加到 C 上的类变量中。然后,每当创建新对象 C 时,它已经具有对回调的引用。
解决方案
一种可能的解决方案是使用元类:
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_())
推荐阅读
- ios - 当使用 Parse 查询数据时,我的视图仅在重复后加载
- laravel - Laravel - 另一个模型中的查询范围不起作用
- javascript - 在 JSP 中的脚本中返回一个 JSON 数组对象
- laravel - 我的 Laravel 站点的视图文件出现了奇怪的问题,这怎么可能?
- wordpress - 错误:找不到内容区域,
- powershell - 运行表单时的Powershell输出问题
- node.js - 在 MongoDB 和 Node.js 中使用聚合方法获取多个数组
- java - 选择特定 JComboBox 项时如何向 JPanel 添加额外的 JButton
- javascript - Javascript:在未定义/空迭代器上捕获 for 循环的最佳方法?
- sql - 仅在条件下使用偏移量获取