如何在 tkinter 中循环创建按钮、文本框和标签 [英] How to create buttons, text boxes and label in loop in tkinter
问题描述
我正在尝试创建一个框架来创建一个标签、文本框和按钮作为一个对象,我可以轻松地扩展它.
I am trying to create a framework to create a label, text box and button as an object, I can extend it easily.
想法:
如果有更多文件,它可以扩展为3、4、5或更多,只需在字典列表中声明,它就会自动扩展.
and it could extend to have 3, 4, 5 or more if it have more file, just declare in dictionary list, it will extend automatically.
我拥有的代码:
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
问题:
默认文件路径仅出现在第二个文本框中.
Default file path appear in second text box only.
所有按钮位置都指向第二个框.
All the button location point to second box.
我也不确定如何在不同的框中获取值,path_loc = obj_name + '_path'"无法获取正确的对象.
I also not sure how could I get the value in different box, the "path_loc = obj_name + '_path'" not able to get the correct object.
我应该如何使它工作?还是我使用的方式不对?
How should I make it work? Or the way I use is wrong?
推荐答案
就在循环中创建它们而言,Tkinter 小部件与任何其他 Python 对象没有什么不同.您的问题似乎是您不知道如何为未知数量的小部件创建唯一变量.
Tkinter widgets are no different than any other python objects with respect to creating them in a loop. Your problem seems to be that you don't know how to create a unique variable for an unknown number of widgets.
要知道的重要一点是,您不需要为每个小部件都使用唯一的变量.相反,您可以使用列表或字典,它们都可以在运行时轻松扩展.
The important thing to know is that you don't need a unique variable for each widget. Instead, you can use a list or dictionary, either of which can be easily extended at runtime.
这是使用字典的解决方案:
Here is a solution using a dictionary:
entries = {}
for key in obj2create:
...
entries[key] = ttk.Entry(...)
...
...
print("the value for file1 is", entries["file1"].get()
创建自定义复合小部件
如果您想要创建一组要被视为一个组的小部件,最好创建一个类.实际上,您正在创建自己的自定义小部件.这种类型的类通常称为复合小部件"或megawidget".
Creating a custom compound widget
If you're wanting to create sets of widgets that are to be treated as a group, it may be better to create a class. In effect, you're creating your own custom widget. This type of class is often called a "compound widget" or "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 中创建每一行:
You can then create each row in your GUI like this:
widgets = {}
for key in obj2create:
widgets[key] = FileWidget(mainFrame, key)
widgets[key].pack(side="top", fill="x")
稍后,您可以像这样取回值:
Later, you can get back the values like this:
for key in obj2create:
widget = widgets[key]
print("%s: %s" % (key, widget.get_path())
这篇关于如何在 tkinter 中循环创建按钮、文本框和标签的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!