在从字符串列表创建PyQt菜单的后续工作中,我也在动态创建菜单并想知道单击了哪个菜单项。因此我使用了一段代码,例如:
for item in ADDABLE_OBJECTS:
action = self.menuAdd.addAction(item)
l = lambda item=item: self.doStuff(item)
action.triggered.connect(l)
def doStuff(self, item):
print "Item: ", item
输出:
Item:False(Qt 文档中针对触发()信号所述的默认“bool”参数)
我认为与 connect(object, SIGNAL(...), slot) 相比,object.connect() 是“新”形式。我也工作得更好,因为可以在编译时检查信号名称。 然而,这并没有奏效。我所通过的只是“bool=false”(如 Qt 文档中的Triggered()所述)。所以搜索后发现了上面提到的网址。不,我有这个:
for item in ['One', 'Two', 'Three']:
action = self.menuAdd.addAction(item)
l = lambda item=item: self.doStuff(item)
action.triggered.connect(l)
self.connect(action, SIGNAL('triggered()'), l)
这给出了(单击菜单一次):
Item:False(action.triggered.connect(l) 行,错误) 项目:一根(self.connect 线,右)
为什么这两者的行为不同?我之前从未注意到这两种连接之间有任何区别,直到我使用了这种 lambda 构造。
这不是关于
lambda
,而是如何在 Qt 中实现带有默认参数的信号。
void triggered(bool = 0)
实际上是两个信号:
void triggered(bool)
void triggered()
PyQt 文档 提到此信号的默认重载为
triggered(bool)
,并且由于您的函数接受参数,因此它可以成功将此信号连接到您的函数。因此,为 bool
传递 item
参数。
您可以通过索引语法选择特定的重载。在这种情况下,您想要不带参数的信号,因此您可以这样做:
action.triggered[()].connect(l)