【问题标题】:Tkinter unexpected behaviourTkinter 意外行为
【发布时间】:2011-04-27 04:33:54
【问题描述】:

我一直在使用 Tkinter 在 Python 中编写一个很长的 GUI。我不明白的一件事是为什么我不能将事件绑定到循环中的小部件。在下面的代码中,如果我手动(注释掉代码)而不是在 for 循环中进行绑定,则绑定效果很好。我做错了吗?

导入 Tkinter

root = Tkinter.Tk()

b1 = Tkinter.Button(root, text="Button 1")
b1.pack()
b1.focus_set()
b2 = Tkinter.Button(root, text="Button 2")
b2.pack()
b3 = Tkinter.Button(root, text="Button 3")
b3.pack()


def up_and_down(*buttons):

  for i in range(len(buttons)-1):
    buttons[i].bind("<Down>", lambda x: buttons[i+1].focus_set())

  for i in range(1, len(buttons)):
    buttons[i].bind("<Down>", lambda x: buttons[i-1].focus_set())

  '''
  buttons[0].bind("<Down>", lambda x: buttons[1].focus_set())
  buttons[1].bind("<Down>", lambda x: buttons[2].focus_set())

  buttons[1].bind("<Up>", lambda x: buttons[0].focus_set())
  buttons[2].bind("<Up>", lambda x: buttons[1].focus_set())
  '''

up_and_down(b1, b2, b3)

root.mainloop()

【问题讨论】:

  • 如果可以添加正在产生的错误就好了。
  • 这可能与您在循环中未使用 "&lt;Up&gt;" 的事实有关吗?
  • @pyfunc 例如,当我按下向下箭头时,我收到此错误。 Tkinter 回调 Traceback 中的异常(最近一次调用最后一次):文件“/usr/lib/python2.6/lib-tk/Tkinter.py”,第 1413 行,在 call 中返回 self.func(* args) 文件“events.py”,第 17 行,在 按钮[i].bind("", lambda x: buttons[i+1].focus_set()) IndexError: tuple index out of range
  • @Nathon 哎呀!在第二个循环中,事件应该是“”。对不起!但我认为这与问题无关。下面的答案显示了我做错了什么。感谢您的评论。

标签: python events user-interface loops tkinter


【解决方案1】:

您的闭包 (lambdas) 未按预期工作。他们保留对 i 的引用,随着循环的迭代,它会发生变化,最后来自同一个循环的所有 lambda 都引用同一个最后一个按钮。

以下是该行为的说明:

>>> k = []
>>> for i in range(5):
...     k.append(lambda: i)
>>> k[0]()
4
>>> [f() for f in k]
[4, 4, 4, 4, 4]

【讨论】:

  • 这不是关于 lambdas,而是关于闭包。你可以在循环中用def而不是lambda定义一个函数,结果是一样的。
【解决方案2】:

您可以通过以下方式解决问题:

for i in range(len(buttons)-1):
    buttons[i].bind("<Down>", lambda x, i=i: buttons[i+1].focus_set())

for i in range(1, len(buttons)):
    buttons[i].bind("<Down>", lambda x, i=i: buttons[i-1].focus_set())

注意 lambda 闭包的 i=i 参数。

【讨论】:

    猜你喜欢
    • 2013-04-05
    • 2017-08-16
    • 2020-09-16
    • 1970-01-01
    • 1970-01-01
    • 2017-03-10
    • 2019-05-01
    • 2011-07-15
    • 2019-12-07
    相关资源
    最近更新 更多