我是相对Python和tkinter的新手。我正在尝试为列表中的每个项目创建一个按钮。
from tkinter import *
x = ['d', 'f']
class GUI:
def __init__(self, master):
self.master = master
master.title("window")
self.label = Label(master, text="Window")
self.label.grid(columnspan=5, sticky=W+E)
self.close_button = Button(master, text="Close", command=master.destroy)
self.close_button.grid(columnspan=5, sticky=W+E)
for s in x:
self.s_button = Button(master, text=s, command=self.s)
self.s_button.grid(columnspan=5, sticky=W+E)
for a in x:
def a(self):
print (a)
root = Tk()
gui = GUI(root)
root.mainloop()
每当我运行代码时,都会收到错误AttributeError: 'GUI' object has no attribute 's'
。
答案 0 :(得分:1)
第一个错误:command=self.s
查找名为" s"的属性。如果要查找名称为s变量内容的属性,则应编写command=getattr(self, s)
。
第二个错误:def a(self)
定义了一个名为" a"的类方法。如果要以编程方式生成命名方法,可以在之后创建类,如下所示:
for a in x:
def fun(self):
print (a)
setattr(GUI, a, fun)
编辑:这仍然是错误的,因为两个函数都使用相同的变量a
。
无论如何,以这种方式生成方法看起来很奇怪,我宁愿使用单个方法将内容作为参数打印,例如:
from tkinter import *
x = ['d', 'f']
class GUI:
def __init__(self, master):
self.master = master
master.title("window")
self.label = Label(master, text="Window")
self.label.grid(columnspan=5, sticky=W+E)
self.close_button = Button(master, text="Close", command=master.destroy)
self.close_button.grid(columnspan=5, sticky=W+E)
for s in x:
self.s_button = Button(master, text=s, command=(lambda: self.print_(s)))
self.s_button.grid(columnspan=5, sticky=W+E)
def print_(self, a):
print (a)
root = Tk()
gui = GUI(root)
root.mainloop()
编辑:由于for循环不创建新范围,因此共享的s变量仍然是错误的。只有函数才能创建新的范围。这是一些有效的代码:
from tkinter import *
x = ['d', 'f']
class GUI:
def __init__(self, master):
self.master = master
master.title("window")
self.label = Label(master, text="Window")
self.label.grid(columnspan=5, sticky=W+E)
self.close_button = Button(master, text="Close", command=master.destroy)
self.close_button.grid(columnspan=5, sticky=W+E)
for s in x:
self.s_button = Button(master, text=s, command=self.make_printer(s))
self.s_button.grid(columnspan=5, sticky=W+E)
def make_printer(self, a):
def fun():
print (a)
return fun
root = Tk()
gui = GUI(root)
root.mainloop()