PyQt QObject.connect(instancemethod)和QtCore.connect(Qobj,SIGNAL(),instancemethod)的行为与la​​mbda函数不同

时间:2012-07-04 13:48:07

标签: lambda pyqt signals connect slot

在跟进Create PyQt menu from a list of strings后,我还在动态创建菜单,并想知道点击了哪个菜单项。因此我使用了一段代码:

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

输出继电器:

  

项目:False(默认'bool'param,如Qt Docs中所述触发()信号)

正如我认为,与connect(object,SIGNAL(...),slot)相比,object.connect()是'new'形式。我也工作得更好,因为可以在编译时检查信号名称。 但是,它没有用。我通过的只是'bool = false'(如针对triggered()的Qt文档中所述)。所以搜索后发现上面提到的url。不,我有这个:

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)

给出(点击菜单一次):

  

项目:False(action.triggered.connect(l)行,错误)   项目:一个(self.connect行,右)

为什么这两个表现不一样?我之前从未注意到两种连接之间存在任何差异,直到我使用这种lambda构造。

1 个答案:

答案 0 :(得分:0)

它不是关于lambda,而是关于如何在Qt中实现具有默认参数的信号。

void triggered(bool = 0)

实际上是两个信号:

void triggered(bool)
void triggered()

PyQt docs提到此信号的默认重载为triggered(bool),并且由于您的函数接受参数,因此它可以成功将此信号连接到您的函数。因此,bool传递item参数。

You can choose specific overloads by indexing syntax。在这种情况下,您希望信号没有参数,因此您可以这样做:

action.triggered[()].connect(l)