如何在 tkinter 中循环创建按钮、文本框和标签 [英] How to create buttons, text boxes and label in loop in tkinter

查看:74
本文介绍了如何在 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

问题:

  1. 默认文件路径仅出现在第二个文本框中.

  1. 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆