PyQt - 从字典创建按钮
我有一本字典。
我需要创建带有键名称的按钮,并根据值创建clicked
插槽:
dic = {'a':'111', 'b':'222', 'c':'333'}
for key in dic:
btn = QPushButton(key, self)
btn.clicked.connect(lambda: doit(dic[key]))
vbox.addWidget(btn)
我拥有所有具有正确名称的按钮。最后创建的按钮行为正常。
但所有其他按钮的 clicked
插槽也连接到最后创建的按钮 do('333')
。
如何使所有按钮的行为不同?
I have a dictionary.
I need to create buttons with keys name, and clicked
slot based on value:
dic = {'a':'111', 'b':'222', 'c':'333'}
for key in dic:
btn = QPushButton(key, self)
btn.clicked.connect(lambda: doit(dic[key]))
vbox.addWidget(btn)
I have all buttons with right name. And last created button behave rightly.
But all others buttons' clicked
slots are also connected to the last created button do('333')
.
How can I make all buttons behave differently?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
匿名函数
lambda: doit(dic[key])
在调用该函数之前不会计算key
。此时,for-loop
已完成,for-loop
变量key
引用dic
中的最后一个键代码>.当调用匿名函数时(当您按下按钮时),将在全局命名空间中查找
key
,并返回key
的当前值。为了避免这个陷阱,您可以在 lambda 表达式中使用默认参数:
默认参数在定义时计算,而不是在调用 lambda 时计算。通过这样做,
key
在匿名函数的本地命名空间中查找,而不是在全局命名空间中查找,并且由于 key 的本地命名空间值被设置为默认值,每个值都不同通过 for 循环,您将获得key
的正确值。这个SO答案也对此进行了解释。
The anonymous function
lambda: doit(dic[key])
does not evaluatekey
until the function is called. By that time, thefor-loop
has completed, and thefor-loop
variablekey
references the last key indic
.When the anonymous function is called (when you press a button),
key
is looked up in the global namespace, and the current value ofkey
is returned.To avoid this pitfall, you can use a default argument in the
lambda
expression:Default arguments are evaluated at definition-time instead of at the time when the lambda is called. By doing this,
key
is looked up in the local namespace of the anonymous function, rather than in the global namespace, and since the local namespace value for key is set to the default value which is different for each pass through the for-loop, you obtain the right value forkey
.This is also explained in this SO answer.
我认为问题是,当您调用 lambda: doit(dic[key]) 时,它实际上就是这样做的,并查找 dic[key],此时 key 设置为迭代的最后一项,
尝试以下操作:
I think the problem is that when you call lambda: doit(dic[key]), it does literally that, and looks up dic[key], and at that time key is set to whatever the last item iterated through was
try this:
您的迭代需要字典 dic 的键和值。
您可以使用 dict.iteritems() 方法。
如果 lambda 变得令人困惑,那么最好使用partial。
试试这个:
your iteration needs keys and values of dictionary dic.
You can use dict.iteritems() method.
If lambda is getting confusing, then is better to use partial.
Try this: