PyQt / Pyside - 创造&动态连接 - 捕获lambda中的函数和参数

时间:2014-12-08 05:03:56

标签: python lambda pyqt pyside getattr

我试图重新创建Windows记事本。

我目前正在弄乱QMenuBar

我用以下模式制作了一个包含所有菜单和动作的字典:

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

然后我遍历那个dict,成功创建菜单和动作并将它们存储在第二个字典中。

现在我尝试将每个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。

1 个答案:

答案 0 :(得分:2)

发现我的错误:

问题是funcmenus上的每次迭代都被覆盖。

通过更改:

来修复它
action.triggered.connect(lambda arg=action:func(arg))

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

后者的工作原理是因为存储了对func的引用,它是由lambda中的默认参数立即获取的。