gpt4 book ai didi

Python Tkinter - 名称未定义

转载 作者:行者123 更新时间:2023-12-01 05:40:52 24 4
gpt4 key购买 nike

代码:

def createLetters(frame, startX, startY, width, height, spacing):

alphabet = ["A", "B", "C", "D", "E", "F", "G", "H", "I",
"J", "K", "L", "M", "N", "O", "P", "Q", "R",
"S", "T", "U", "V", "W", "X", "Y", "Z"]

def letterAction(letter):
letter.destroy()

for i in range(0, 26):

if (i >= 9 and i <= 17):
y = startY + height + 2 * spacing
x = startX + ((width + spacing) * (i - 9))

elif (i >= 17):
y = startY + 2 * height + 3 * spacing
x = (width + spacing) / 2 + startX + ((width + spacing) * (i - 18))

elif (i <= 8):
y = startY + spacing
x = startX + ((width + spacing) * i)

exec(alphabet[i] + " = Button(" + frame + ", text = '" + alphabet[i] + "', command = letterAction(" + alphabet[i] + "))")
exec(alphabet[i] + ".place(x = " + str(x) + ", y = " + str(y) + ", width = " + str(width) + ", height = " + str(height) + ")")

错误:

Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Python33\lib\tkinter\__init__.py", line 1442, in __call__
return self.func(*args)
File "E:\Hangman\hangmanTk.py", line 106, in playScreen
createLetters("playFrame", 175, 250, 50, 50, 0)
File "E:\Hangman\hangmanTk.py", line 95, in createLetters
exec(alphabet[i] + " = Button(" + frame + ", text = '" + alphabet[i] + "', command = letterAction(" + alphabet[i] + "))")
File "<string>", line 1, in <module>
NameError: name 'A' is not defined

我正在尝试创建多个带有循环的 tkinter 按钮。我可以很好地创建按钮,但我似乎无法为它们创建回调。当我尝试时,它告诉我用于按钮的变量未定义。我尝试在定义按钮的位置添加“exec("global "+ Alphabet[i])”,但这并没有改变任何内容。

最佳答案

Using exec is almost always the wrong way to do it, no matter what "it" is.

And creating variables dynamically is almost always the wrong thing to do.

您在使其正常工作时遇到的问题完美地说明了原因。

<小时/>

只需创建一个 dict将名称映射到按钮:

buttons = {}

# ...

letter = alphabet[i]
buttons[letter] = Button(frame, text = letter, command = letterAction(letter))
buttons[letter].place(x = x, y = y, width = width, height = height)

如果你真的想转储dict进入locals() (或者,类似地,self.__dict__globals()或...),这很简单。但你没有。您唯一需要使用该变量的地方是在 letterAction 中。功能。所以:

def createLetters(frame, startX, startY, width, height, spacing):

alphabet = string.ascii_uppercase
buttons = {}

def letterAction(letter):
buttons[letter].destroy()

for i, letter in enumerate(alphabet):

if (i >= 9 and i <= 17):
y = startY + height + 2 * spacing
x = startX + ((width + spacing) * (i - 9))

elif (i >= 17):
y = startY + 2 * height + 3 * spacing
x = (width + spacing) / 2 + startX + ((width + spacing) * (i - 18))

elif (i <= 8):
y = startY + spacing
x = startX + ((width + spacing) * i)

buttons[letter] = Button(frame, text = letter, command = letterAction(letter))
buttons[letter].place(x = x, y = y, width = width, height = height)
<小时/>

但请注意,这样做是错误的。 command = letterAction(letter) —无论您直接运行它,还是通过 exec 运行它—要打电话letterAction(letter)现在,在创建按钮之前就将其销毁,并返回 None ,然后将其设置为 command

您需要lambda: letterAction(letter)partial(letterAction, letter)来解决这个问题。

另外,您无法编写代码将按钮变量本身传递给 letter ,无论是现在还是以后,因为该变量尚不存在。您必须将字母作为字符串传递,就像我上面所做的那样。

<小时/>

但实际上,如果您仔细想想,您根本不需要这些按钮变量 — 无论是在 dict 中或其他方式。您只需要一种方法将每个按钮绑定(bind)为其自己的回调目标,对吧?有多种方法可以做到这一点,但最明显的方法是类,继承或委托(delegate)给 Button (或者,在本例中,两者都不需要,因为您不需要将其用作按钮,甚至在创建后不需要记住它)。

当我们这样做时,让我们删除一些无关的括号,这样只会让事情更难阅读并解决 17 的问题。似乎属于两个不同的群体......

class SelfDestructiveButton(object):
def __init__(self, frame, letter, x, y, width, height):
self.button = Button(frame, text=letter, command=self.command)
self.button.place(x=x, y=y, width=width, height=height)
def command(self):
self.button.destroy()

def createLetters(frame, startX, startY, width, height, spacing):
for i, letter in enumerate(string.ascii_uppercase):
if 9 <= i <= 17:
y = startY + height + 2 * spacing
x = startX + ((width + spacing) * (i - 9))
elif i > 17:
y = startY + 2 * height + 3 * spacing
x = (width + spacing) / 2 + startX + ((width + spacing) * (i - 18))
else:
y = startY + spacing
x = startX + ((width + spacing) * i)
SelfDestructiveButton(frame, letter, x, y, width, height)

使用 if 'J' <= letter <= 'R' 可能会更清楚,因为调试时您将看到的是字母而不是数字。

关于Python Tkinter - 名称未定义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17580340/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com