如何在tkinter

时间:2016-10-01 06:18:06

标签: python tkinter

我正在尝试创建一个框架来创建标签,文本框和按钮作为对象,我可以轻松扩展它。

点子:

Original

after extend

如果它有更多的文件,它可以扩展为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

问题:

  1. 默认文件路径仅显示在第二个文本框中。

  2. 所有按钮位置都指向第二个框。

  3. 我也不确定如何在不同的框中获取值," path_loc = obj_name +' _path'"无法获得正确的对象。

    我该如何使它发挥作用?或者我使用的方式是错的?

1 个答案:

答案 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())