Tkinter 意外行为

发布于 2024-09-28 04:34:33 字数 934 浏览 0 评论 0原文

我一直在使用 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()

I've been writing a long GUI in Python using Tkinter. One thing that I don't understand is why I can't bind events to widgets in a loop. In the code below, binding works well if I do it manually (commented out code) but not in a for loop. Am I doing something wrong?

import 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()

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

冬天旳寂寞 2024-10-05 04:34:33

您的闭包(lambda)没有按照您的预期工作。它们保留对 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]

Your closures (lambdas) are not working as you expect them to. They keep references to i which is mutated as the loop iterates, and in the end all lambdas from the same loop refer to the same single last button.

Here's an illustration of the behaviour:

>>> k = []
>>> for i in range(5):
...     k.append(lambda: i)
>>> k[0]()
4
>>> [f() for f in k]
[4, 4, 4, 4, 4]
不弃不离 2024-10-05 04:34:33

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

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 参数。

You can fix the problem with:

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())

Note the i=i argument to the lambda closure.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文