使用Python中的数组变量在循环中命名按钮的函数

时间:2014-04-19 23:21:14

标签: python button scope tkinter

作为向Python自我介绍的一种方式,我决定复制Windows附带的基本计算器。我已经设法解决了初始问题,即使用vars()函数命名通过循环创建的各个按钮,其中存储在数组中的变量(有点杂乱无章,我知道)。但是,当我将循环封装在函数中时,这不起作用。

阵列:

controls = [
    ["zer", "0", 0, 18, 150, 30, 70],
    ["one", "1", 1, 18, 115, 30, 35],
    ["two", "2", 2, 54, 115, 30, 35]
]

这有效:

for b in controls:
    vars()[b[0]] = Button(calc, text=b[1], command=lambda inp=b[2]:click(inp))
    vars()[b[0]].place(x=b[3], y=b[4], height=b[5], width=b[6])

在尝试调整其中一个按钮的状态时返回NameError:

def setButtons(buttons)
    for b in buttons:
        vars()[b[0]] = Button(calc, text=b[1], command=lambda inp=b[2]:click(inp))
        vars()[b[0]].place(x=b[3], y=b[4], height=b[5], width=b[6])

setButtons(controls)

我知道数组被传递给函数,因为按钮仍然生成并且表现良好。这是我在使用vars()函数之前遇到的确切问题,所以我猜这将是一个范围问题。我还应该注意到我还没有考虑使用字典,我担心它可以完全解决这个问题,并且不需要使用vars()。

有人有什么想法吗?

1 个答案:

答案 0 :(得分:0)

没有理由使用vars。简单的解决方案是将所有小部件存储在字典中:

self.buttons = {}
for b in controls:
    self.buttons[b[0]] = Button(...)

使用place也没有充分的理由 - place有它的优点,但它们很少而且很远。如果您使用packgrid,您的GUI将更容易编写和维护。对于计算器,grid是一个非常自然的选择。此外,尝试在数据结构中定义布局是麻烦的。我不确定它是否具有任何实际价值,因为您不太可能会创建一个可以使用不同编号系统创建计算器的通用算法。

我建议将窗口小部件的布局与窗口小部件的创建分开。根据我的经验,简单地使GUI开发更容易。

self.buttons["zer"].grid(row=3, column=0, columnspan=2, sticky="nsew")
self.buttons["two"].grid(row=2, column=0, sticky="nsew")
self.buttons["thr"].grid(row=2, column=1, sticky="nsew")
...

另外,我建议不要使用" zer"等名称。 - 将四个字母的单词缩写为三个字母并没有什么价值。