代码之家  ›  专栏  ›  技术社区  ›  Jason H

如何使tkinter按钮与标签和输入框保持在同一行

  •  0
  • Jason H  · 技术社区  · 7 年前

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

    我已经阅读了tkinter教程。我从同事和网络上尝试了三种不同的框架想法。我确实试着把它放在一个元素中,但不是我的大脑被炸了,就是我还不足以理解它是如何工作的。我认为网格可能是我的答案,但由于这是我第一次尝试这样的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()  
    

    我希望浏览按钮旁边的输入字段,而不是它的当前位置下的确定和关闭按钮。

    次要问题。。。我想不出如何让我的回叫工作!

    1 回复  |  直到 7 年前
        1
  •  3
  •   stovfl    7 年前

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

    要做到这一点,你必须 pack 这个 Entry Button 变成自己的 Frame

    笔记 :始终使用 side=tk.LEFT 将小部件排成一行。

    此示例显示了一个 OOP 解决方案: enter image description here

    • 定义一个 class LabelEntry tk.Frame .

      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)
      
    • 按钮 通过,创建一个新的 框架 这个 进入 按钮 .

              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