总共60个tkinter条目,名为e0,e1 .... e59,60标签为l0,l1 .... l59。该功能可以正常工作。 Version_one:
def CreateCharacter():
root.destroy()
chcreation = tk.Tk()
global e0, e1,..... e59
l0 = tk.Label(chcreation, text=char[0], fg='black')
l0.grid(row=0, column=0)
e0 = tk.Entry(chcreation, fg='black')
e0.grid(row=1, column=0)
...........
e59 = tk.Entry(chcreation, fg='black')
e59.grid(row=1, column=0)
但是,如果我像下面那样切换到“ exec”方法,则另一个函数无法使用 global 变量e0 e1 .... e59来收集输入。 第二版:
def CreateCharacter():
root.destroy()
chcreation = tk.Tk()
chcreation.title('create new character')
chcreation.geometry('1100x500+50+100')
global e0, e1, ..... e59
for i in range(60):
ro = (i // 11) * 2
col = i % 11
exec("l%s=tk.Label(chcreation,text=char[%d])" % (i,i))#char is a name list
exec("l%s.grid(row=ro,column=col, padx=5, pady=2)" % i)
exec("e%s=tk.Entry(chcreation, fg='black',width=12)" % i)
exec("e%s.grid(row=ro+1,column=col, padx=5, pady=2)" % i)
标签和条目在“创建”窗口中显示良好,但是当其他函数调用此函数时,错误为“ NameError:未定义名称'e0'”。但是我全局定义了它们,并且在Version_one版本中它们可以正常工作。请指教。
调用函数如下:
def Charater_creating(en):
crole = []
for i in range(60):
exec("crole.append(e%s.get())"%i)
raw_data = pd.DataFrame(crole, index=mul_index)
raw_data.to_csv('char.csv',header=False,mode='a')
for i in range(60):
exec("e%s.delete(0,'end')"%i)
整个代码:
import pandas as pd
import tkinter as tk
array_index = [['Basic', 'Basic' ],['Name', 'Nickname']]
char = array_index[1]
mul_index = pd.MultiIndex.from_arrays(array_index)
role = pd.DataFrame([], index=mul_index)
def CreateCharacter():
root.destroy()
chcreation = tk.Tk()
chcreation.geometry('1200x500+50+100')
global e0, e1
#error block
for i in char:
t = char.index(i)
ro = (t // 11) * 2
col = t % 11
exec("l%s=tk.Label(chcreation,text=char[%d])" % (t, t))
exec("l%s.grid(row=ro,column=col, padx=5, pady=2)" % t)
exec("e%s=tk.Entry(chcreation, fg='black',width=12)" % t)
exec("e%s.grid(row=ro+1,column=col, padx=5, pady=2)" % t)
#below is the working block
# l0 = tk.Label(chcreation, text=char[0], font=('Arial', 12), fg='black')
# l0['height'] = 2
# l0['width'] = 8
# l0.grid(row=0, column=0)
# e0 = tk.Entry(chcreation, font=('Arial', 10), fg='black')
# e0['width'] = 8
# e0.grid(row=1, column=0)
# l1 = tk.Label(chcreation, text=char[1], font=('Arial', 12), fg='black')
# l1['height'] = 2
# l1['width'] = 8
# l1.grid(row=0, column=1)
# e1 = tk.Entry(chcreation, font=('Arial', 10), fg='black')
# e1['width'] = 8
# e1.grid(row=1, column=1)
creat_button = tk.Button(chcreation, text='OK', font=('Arial', 8), fg='black')
creat_button['width'] = 8
creat_button['height'] = 2
creat_button.grid(row=11, column=5)
creat_button.bind('<Button-1>', Charater_creating)
def Charater_creating(en):
crole = [e0.get(), e1.get()]
raw_data = pd.DataFrame(crole, index=mul_index)
raw_data.to_csv('character_data11.csv', header=False, mode='a')
e0.delete(0, 'end')
e1.delete(0, 'end')
root = tk.Tk()
root.geometry('900x400+200+50')
c_cbutn = tk.Button(root, text='new', font=('Arial', 20), fg='red', command=CreateCharacter)
c_cbutn['height'] = 2
c_cbutn['width'] = 15
c_cbutn.grid(row=3, column=1)
root.mainloop()
答案 0 :(得分:0)
这可能是问题所在;在带有exec
的代码中,您可以使用以下内容创建条目:
exec("e%s_Entry=tk.Entry(chcreation, fg='black',width=12)" % i)
为小部件分配名称:e0_Entry, e1_Entry, ... etc.
。因此将不会定义名称e0, e1, ... etc.
。
其他想法
我发现了问题,但不知道为什么。请考虑以下功能:
def go_a():
global a
a = 25
print(a)
go_a() # This works just fine
def go_b():
global b
exec("b = 25")
print(b)
go_b() # Generates NameError: name 'b' is not defined
由于某种原因,使用exec
函数的函数不会在全局名称空间中设置名称“ b”,除非该名称已经存在。见下文:
b = 9 # Setting the name "b"
go_b() # As if by magic, this now works
所以这是exec
和范围的问题,但我真的不明白为什么。
我的建议是将条目存储在列表或字典中,就像布莱恩建议的那样。
答案 1 :(得分:0)
永远不要使用exec
创建变量。这使得代码几乎不可能理解和维护。
如果要创建大量的小部件(或任何类型的对象),请将它们存储在列表或字典中。
widgets = []
for i in range(60):
ro = (i // 11) * 2
col = i % 11
widget = tk.Label(chcreation,text=i)
widgets.append(widget)
您现在可以使用诸如widgets[0]
,widgets[1]
之类的东西来引用每个标签。如果您的索引是整数并且从零开始,则可以很好地使用该标签。
-或-
widgets = {}
...
widgets[i] = widget
当您的索引不是整数时,上述方法效果更好。与列表一样,您仍然以相同的方式引用小部件(例如:widgets[0]
等)