我正在尝试创建一个框架来创建标签,文本框和按钮作为对象,我可以轻松扩展它。
点子:
如果它有更多的文件,它可以扩展为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(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
问题:
默认文件路径仅显示在第二个文本框中。
所有按钮位置都指向第二个框。
我也不确定如何在不同的框中获取值," path_loc = obj_name +' _path'"无法获得正确的对象。
我该如何使它发挥作用?或者我使用的方式是错的?
答案 0 :(得分:1)
Tkinter小部件与在循环中创建它们的任何其他python对象没有什么不同。您的问题似乎是您不知道如何为未知数量的小部件创建唯一变量。
重要的是要知道每个小部件不需要唯一的变量。相反,您可以使用列表或字典,其中任何一个都可以在运行时轻松扩展。
以下是使用字典的解决方案:
entries = {}
for key in obj2create:
...
entries[key] = ttk.Entry(...)
...
...
print("the value for file1 is", entries["file1"].get()
如果您想要创建要视为一个组的小部件集,那么创建一个类可能更好。实际上,您正在创建自己的自定义小部件。这种类通常称为“复合小部件”或“兆小部件”。
例如:
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())