【发布时间】:2014-03-05 06:25:25
【问题描述】:
我是 PySide 的新手,并试图弄清楚如何优雅地创建有效的信号扇出;即一个看起来像容器类的插槽的小玩意儿,因此可以被连接(),并简单地将信号转发到包含的类,最好不要在语法或性能上增加太多开销。
让我们举一个完全人为的例子:
class TripleCheckBox(QWidget):
setCheckState = Signal(int)
def __init__(self, parent):
super().__init__(parent)
self.checks = [QCheckBox(x, self) for x in ['One', 'Two', 'Three']]
[self.setCheckState.connect(x) for x in self.checks]
class MainWindow(QWidget):
def __init__(self):
self.chk = QCheckBox('Alpha', self)
self.btn = QPushButton('Push', self)
self.tri = TripleCheckBox(self)
self.chk.stateChanged.connect(self.tri.setCheckState)
self.btn.clicked.connect(self.clearChecks)
def clearChecks(self):
self.tri.setCheckState(0)
所以,这可以满足我的大部分需求。来自 Alpha 复选框的 stateChanged 信号击中 TripleCheckBox 上的信号端口,然后重新广播到 One、2 和 Three,并且(我相信)完全在 Qt 库中这样做,而不必在库代码和 Python 之间来回切换.
但是MainWindow.ClearChecks() 不起作用。对于一个真正的 QCheckBox,setCheckState 是一个 Slot,因此是一个函数,可以用常规的函数语法调用。但是 TripleCheckBox 上的 setCheckState 是一个信号,因此必须“调用”为self.tri.setCheckState.emit(0)
这在语法上很丑陋,但也有一些丑陋的可维护性含义。如果我有一个 QCheckBox,我可以将 setCheckState 视为一个函数。如果我有一个 TripleCheckBox,我必须将其视为一个信号,即使它所做的只是包装 3 个 QCheckBox。
理想情况下,TripleCheckBox.setCheckState 应该是一个类似 Signal 的东西,它只是有一个 __call__ 方法,它调用/是 emit。但是你不能从 Signal 继承。
我可以想到几种不优雅的方法来做到这一点,所有这些都涉及大量的代码复制和临时性。但这是一些非常基本的东西,肯定有一个优雅的答案。对吧?
【问题讨论】:
标签: python pyside signals-slots