【问题标题】:How to keep tkinter button on same row as label and entry box如何将 tkinter 按钮与标签和输入框保持在同一行
【发布时间】:2019-02-08 01:00:06
【问题描述】:

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

我已阅读 tkinter 教程。我从同事和网络上尝试了三种不同的 Frame 创意。我确实试图把它放在一个元素中,但要么我的大脑被炒了,要么我还不够好,无法理解它是如何工作的。我认为网格可能是我的答案,但由于这是我尝试过的第一个 UI,我无法按照代码进行操作。

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

我想要输入字段旁边的“浏览”按钮,而不是使用“确定”和“关闭”按钮将其当前位置向下。

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

【问题讨论】:

  • 你知道pack有几个选项,如果你不明确告诉它做什么,它会从上到下堆叠小部件?

标签: python python-3.x tkinter


【解决方案1】:

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

要达到此目的,您必须将pack EntryButton 转换为自己的 Frame

注意:始终使用side=tk.LEFT 来获取连续的小部件。

此示例显示了OOP 解决方案:

  • 定义一个继承自tk.Frameclass 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通过,则创建一个新的FramepackEntryButton

            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))
    
  • 运行应用程序。

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

用 Python 测试:3.5

【讨论】:

  • 使用 Python 3.6.8,运行解决方案时出现以下错误:AttributeError: '_tkinter.tkapp' object has no attribute 'callback' 这是关于代码行:button = tk.Button(text="Browse", command=self.callback)
猜你喜欢
  • 2015-06-07
  • 1970-01-01
  • 1970-01-01
  • 2011-12-19
  • 2016-10-15
  • 1970-01-01
  • 1970-01-01
  • 2022-10-17
  • 1970-01-01
相关资源
最近更新 更多