如何将 tkinter 按钮与标签和输入框保持在同一行 [英] How to keep tkinter button on same row as label and entry box

查看:661
本文介绍了如何将 tkinter 按钮与标签和输入框保持在同一行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在创建一个简单的条目 UI 来接收 2 个文本字段和一个文件夹路径.我刚刚开始使用 tkinter,我无法让浏览按钮出现在 CSV 文件的输入字段旁边.相反,它与其他按钮一起出现.

I am creating a simple entry UI to intake 2 text fields and a folder path. I'm just getting started with tkinter and I can't get the browse button to appear next to the entry field for the CSV file. Instead it appears with the other buttons.

我已经阅读了 tkinter 教程.我已经尝试了来自同事和网络的三种不同的 Frame 创意.我确实尝试将它放入一个元素中,但要么我的大脑被炸了,要么我不够好,无法理解它是如何工作的.我认为网格可能是我的答案,但由于这是我尝试过的第一个 UI,我无法遵循代码.

I have read the tkinter tutorial. I've tried three different Frame ideas from coworkers and the web. I did try to put this in an element, but either my brain is fried or I'm just not good enough to understand how that works. I think grids might be my answer, but as this is the first UI I've tried like this I can't follow the code.

import tkinter as tk
fields = 'Version', 'Database Name', 'CSV File'

def fetch(entries):
    for entry in entries:
        field = entry[0]
        text  = entry[1].get()
        print('%s: "%s"' % (field, text))

def callback():
    path = tk.filedialog.askopenfilename()
    entry.delete(0, tk.END)
    entry.insert(0, path)

def initUI(root, fields):
    entries = []
    for field in fields:
        if field == 'CSV File':
            frame = tk.Frame(root)
            frame.pack(fill=tk.X)

            lbl = tk.Label(frame, text=field, width=20, anchor='w')
            lbl.pack(side=tk.LEFT, padx=5, pady=5)           

            entry = tk.Entry(frame)
            entry.pack(fill=tk.X, padx=5)

            btn = tk.Button(root, text="Browse", command=callback)
            btn.pack(side=tk.RIGHT,padx=5, pady=5)

            entries.append((field, entry))
        else:
            frame = tk.Frame(root)
            frame.pack(fill=tk.X)

            lbl = tk.Label(frame, text=field, width=20, anchor='w')
            lbl.pack(side=tk.LEFT, padx=5, pady=5)           

            entry = tk.Entry(frame)
            entry.pack(fill=tk.X, padx=5, expand=True)

            entries.append((field, entry))
    return entries

if __name__ == '__main__':
    root = tk.Tk()
    root.title("Helper")
    entries = initUI(root,fields)
    root.bind('<Return>', (lambda event, e=entries: fetch(e))) 
    frame = tk.Frame(root, relief=tk.RAISED, borderwidth=1)
    frame.pack(fill=tk.BOTH, expand=True)

    closeButton = tk.Button(root, text="Close", command=root.quit)
    closeButton.pack(side=tk.RIGHT, padx=5, pady=5)
    okButton = tk.Button(root, text="OK", command=(lambda e=entries: fetch(e)))
    okButton.pack(side=tk.RIGHT)
    root.mainloop()  

我想要输入字段旁边的浏览"按钮,而不是其当前位置下方的确定"和关闭"按钮.

I am wanting the Browse button next to the entry field instead of its current location down with the OK and Close buttons.

附带问题......我不知道如何让我的回调工作!

Side problem... I can't figure out how to get my callback to work!

推荐答案

问题:如何将 tkinter 按钮与标签和输入框保持在同一行

Question: How to keep tkinter button on same row as label and entry box

要达到此目的,您必须将EntryButton pack 打包到自己的Frame 中.

To reach this you have to pack the Entry and Button into a own Frame.

注意:始终使用 side=tk.LEFT 将小部件排成一行.

Note: Use always side=tk.LEFT to get the widgets in a row.

这个例子展示了一个 OOP 解决方案:

This example shows a OOP solution:

  • 定义一个从 tk.Frame 继承的 class LabelEntry.

class LabelEntry(tk.Frame):
    def __init__(self, parent, text, button=None):
        super().__init__(parent)
        self.pack(fill=tk.X)

        lbl = tk.Label(self, text=text, width=14, anchor='w')
        lbl.pack(side=tk.LEFT, padx=5, pady=5)

  • 条件:如果Button通过,创建一个新的FramepackEntry按钮.

  • Condition: If a Button passed, create a new Frame to pack the Entry and Button.

            if button:
                frame2 = tk.Frame(self)
                frame2.pack(side=tk.LEFT, expand=True)
    
                entry = tk.Entry(frame2)
                entry.pack(side=tk.LEFT, fill=tk.X, padx=5)
    
                button.pack(in_=frame2, side=tk.LEFT, padx=5, pady=5)
            else:
                entry = tk.Entry(self)
                entry.pack(side=tk.LEFT, fill=tk.X, padx=5)
    

  • 用法:

    • 定义一个class App继承自tk.Tk.

      class App(tk.Tk):
          def __init__(self):
              super().__init__()
      
              self.title("Helper")
      
              frame = tk.Frame(self)
              frame.grid(row=0, column=0)
      

    • 循环 fields 并创建一个 LabelEntry 对象

              entries = []
              for field in 'Version', 'Database Name', 'CSV File':
                  if field == 'CSV File':
                      button = tk.Button(text="Browse", command=self.callback)
                      entries.append(LabelEntry(frame, field, button))
                  else:
                      entries.append(LabelEntry(frame, field))
      

    • 运行应用程序.

    • Run the Application.

      if __name__ == "__main__":
          App().mainloop()
      

    • 使用 Python 测试:3.5

      这篇关于如何将 tkinter 按钮与标签和输入框保持在同一行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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