代码:
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) + ")")
错误:
^{pr2}$我试图用一个循环创建多个tkinter按钮。我可以很好地创建按钮,但似乎不能为它们创建回调。当我尝试时,它告诉我我用于按钮的变量没有定义。我试着在我定义按钮的地方添加“exec(”global“+alphabet[I])”,但这并没有改变任何东西。在
{a1}
And creating variables dynamically is almost always the wrong thing to do.
而你的问题让它运作起来就是一个完美的例子。在
只需创建一个
dict
映射名称到按钮:如果您真的想将}或…),那么这很简单。但是你没有,你只需要在你的
^{pr2}$dict
转储到locals()
(或者,类似地,self.__dict__
或{letterAction
函数中使用变量。所以:但请注意,这样做是错误的。},然后将其设置为
command = letterAction(letter)
-无论是直接运行还是通过exec
-现在都要调用letterAction(letter)
,在创建之前销毁按钮,并返回{command
。在您需要
lambda: letterAction(letter)
或partial(letterAction, letter)
来修复此问题。在另外,现在或以后都不能编写代码将button变量本身传递给
letter
,因为该变量还不存在。你必须将字母作为字符串传递,就像我上面所做的那样。在但实际上,如果你仔细想想,你根本不需要这些按钮变量,不管是在
dict
中还是在其他地方。你只需要一种方法将每个按钮绑定为它自己的回调目标,对吧?有很多方法可以做到这一点,但最明显的一种方法是类,要么继承或委托给Button
(或者,在本例中,既不需要将其用作按钮,也不需要在创建后记住它)。在当我们在做的时候,让我们去掉一些无关的parens之类的东西,这样会使东西更难阅读,并解决
17
似乎属于两个不同的组的问题使用
if 'J' <= letter <= 'R'
可能会更清楚,因为调试它时您将看到的是字母而不是数字。在第一次调用
exec
中的字符串计算为:因此,您在定义
^{pr2}$A
(名称)之前引用它。我猜你忘了第二个alphabet[i]
左右的单引号:注意这将调用
letterAction('A')
,即'A'.destroy()
,这将抛出一个AttributeError
,因为字符串没有destroy()
方法。letterAction
应该实现什么?在相关问题 更多 >
编程相关推荐