PyQt/Pyside - 创建和连接动态 - 在lambda中捕获函数和参数

问题描述:

我试图重新创建Windows记事本。PyQt/Pyside - 创建和连接动态 - 在lambda中捕获函数和参数

我目前搞乱与QMenuBar

我做了所有的菜单和操作字典它将在以下模式:

menus = {'File':[['New', 'Ctrl+n'], 
       ['Open', 'Ctrl+o'], 
       ['Save', 'Ctrl+s'], 
       ['Save as...', None], 
       'Separator', 
       # and so on 

然后我遍历该字典,创造菜单和操作成功并将它们存储在第二个字典中。

现在我试图将每个action[new, open, save, …]连接到同名的实例方法。

我做像这样:

for action in menus[m]: 
    action = menu.addAction(action[0]) 

    if action[1]: 
     action.setShortcut(QKeySequence(action[1])) 

    if isinstance(action, QAction): 
     fname = action[0].lower() 
     # and some other string manipulations 
     func = getattr(self,fname) 
     action.triggered.connect(lambda arg=action: func(arg)) 

连接成功,但如果我尝试使用任何行动的它什么都不做。

我以前曾使用lambda函数连接过动作,但这是我第一次使用getattr()和lambda在一起。

+0

[Python lambda封闭范围]可能的重复(http://*.com/questions/13355233/python-lambda-closure-scoping) – 2014-12-08 09:33:00

+1

不要使用'__getattribute__':使用'func = getattr(self, FNAME)'。 – ekhumoro 2014-12-08 17:38:40

+0

还没有意识到这两者之间的区别。 – 2014-12-08 17:53:42

找到我的错误:

问题是func渐渐在每个迭代上了menus覆盖。

通过改变固定它:

action.triggered.connect(lambda arg=action:func(arg)) 

action.triggered.connect(lambda f=func,arg=a:f(arg)) 

后者作品因为func参考被存储是通过在拉姆达默认参数立即采取。