Python 如何在tkinter中创建循环中的按钮、文本框和标签
我试图创建一个框架来创建一个标签,文本框和按钮作为一个对象,我可以很容易地扩展它 想法: 如果它有更多的文件,它可以扩展到3、4、5或更多,只要在字典列表中声明,它就会自动扩展 我的守则如下:Python 如何在tkinter中创建循环中的按钮、文本框和标签,python,tkinter,Python,Tkinter,我试图创建一个框架来创建一个标签,文本框和按钮作为一个对象,我可以很容易地扩展它 想法: 如果它有更多的文件,它可以扩展到3、4、5或更多,只要在字典列表中声明,它就会自动扩展 我的守则如下: def getpath(entry_box, type): # path or file if type == 'path': entry_box.set(filedial.askdirectory()) elif type == 'file': entry_box.set(filed
def getpath(entry_box, type):
# path or file
if type == 'path':
entry_box.set(filedial.askdirectory())
elif type == 'file':
entry_box.set(filedial.askopenfilename())
MainWin = tk.Tk() # Create main windows
MainWin.title('Get file and path') # App name
# Create root container to hold Frames
mainFrame = ttk.Frame(MainWin)
mainFrame.grid(column=1, row=1)
# define the object to create in dictionary, format:
# {object name:[title name, default path, button name, file or folder path]}
obj2create ={'file1':['ABC Location: ', r'C:/', 'Get ABC','file'],
'file2': ['DEF Location:', r'C:/1/', 'Get DEF', 'file']}
ttl_obj = 0
for key in obj2create:
ttl_obj +=1
vir = obj2create[key]
# Module for get file:
obj_name = key
title = vir[0]
default_path = vir[1]
btn_name = vir[2]
get_type = vir[3]
# Create main container
pa_frame = ttk.Frame(mainFrame)
pa_frame.grid(column=1, row=10*ttl_obj, sticky=tk.W)
pa_frame.config(width = 100)
# Row 1: Label
frame_name = obj_name + '_name'
print(frame_name)
frame_name = ttk.Label(pa_frame, text= title).grid(column=1, row=10*ttl_obj,sticky=tk.W)
# Row 2: path and button
# assign type
path_loc = obj_name + '_path'
path_loc = tk.StringVar()
path_loc.set(default_path)
# put in frame
fileLocPath = obj_name + '_loc_path'
fileLocPath = ttk.Entry(pa_frame, width=70, textvariable=path_loc)
fileLocPath.grid(column=1, row=30*ttl_obj) # Assign position
# Get file button
# define button display text and assign the command / function
bt_get_file_path = obj_name + '_btn'
bt_get_file_path = ttk.Button(pa_frame, text= btn_name,
command=lambda: getpath(path_loc, get_type))
# Position Button in second row, second column (zero-based)
bt_get_file_path.grid(column=2, row=30*ttl_obj)
# Auto popup when open
MainWin.mainloop() # Let the window keep running until close
问题:
我该怎么做?或者我使用的方法是错误的?Tkinter小部件与任何其他python对象在循环中创建它们方面没有什么不同。您的问题似乎是不知道如何为未知数量的小部件创建唯一变量 需要知道的重要一点是,每个小部件不需要唯一的变量。相反,您可以使用列表或字典,它们中的任何一个都可以在运行时轻松扩展 在字典中保存小部件引用 下面是一个使用字典的解决方案:
entries = {}
for key in obj2create:
...
entries[key] = ttk.Entry(...)
...
...
print("the value for file1 is", entries["file1"].get()
创建自定义复合小部件
如果您想要创建一组要作为一个组处理的小部件,那么最好创建一个类。实际上,您正在创建自己的自定义小部件。这种类型的类通常称为“复合小部件”或“megawidget”
例如:
class FileWidget(ttk.Frame):
def __init__(self, parent, name):
ttk.Frame.__init__(self, parent)
self.label = ttk.Label(self, text="%s Location" % name)
self.fileLocPath = ttk.Entry(self)
self.bt_get_file_path = ttk.Button(self, text=name, command=self.get_path)
...
def get_path(self):
return self.fileLocPath.get()
然后,您可以在GUI中创建每一行,如下所示:
widgets = {}
for key in obj2create:
widgets[key] = FileWidget(mainFrame, key)
widgets[key].pack(side="top", fill="x")
for key in obj2create:
widget = widgets[key]
print("%s: %s" % (key, widget.get_path())
稍后,您可以返回如下值:
widgets = {}
for key in obj2create:
widgets[key] = FileWidget(mainFrame, key)
widgets[key].pack(side="top", fill="x")
for key in obj2create:
widget = widgets[key]
print("%s: %s" % (key, widget.get_path())
如果我理解这一点,您希望在循环中以不同的方式命名每个小部件,但您不能这样做,对吗?是的,因为我需要知道文件ABC和DEF的位置。文件选择器也不起作用,当我按“Get ABC”时,它会更新到DEF文件路径中的文本框。我们使用字典(或列表)来实现这一点-即,
path\u loc[obj\u name]=…
Tks,它确实起作用,我认为这是一个进步,需要时间来理解。