【问题标题】:Python-Tkinter Place button on left of frame框架左侧的 Python-Tkinter 放置按钮
【发布时间】:2018-05-11 11:37:14
【问题描述】:

如何将 QUIT 按钮放在下面代码中 Frame 的最右侧? 我尝试了几件事:

padx

self.pack(side="top", anchor="e")

但是在尝试了大约 15 次之后,两个按钮都彼此靠近了。也许任何人的帮助将不胜感激。我需要一个按钮在最右边,另一个在最左边

import tkinter as tk
from tkinter.ttk import *

class Application(tk.Frame):
    def __init__(self, master=None):
        tk.Frame.__init__(self, master)
        self.pack()
        self.createWidgets()
        self.master.title("Log Parser")
    def createWidgets(self):
        self.Run_Main = tk.Button(self)
        self.Run_Main["text"] = "Browse.."
        # self.Run_Main["fg"] = "blue"
        self.Run_Main["command"] = self.Sayhello
        self.Run_Main.pack(side='left')
        self.Label = tk.Label(self)
        self.Label["text"] = 'Processing...'
        self.progressbar = Progressbar(mode="indeterminate", maximum=20)
        self.QUIT = tk.Button(self)
        self.QUIT["text"] = "Quit!"
        self.QUIT["command"] =  self.quit
        self.QUIT.pack(anchor='e')
        self.pack(side="top", anchor="w")

    def Sayhello(self):
       print("Hello")

# scroll text inside application frame
class scrollTxtArea:
    def __init__(self, root):
        frame = tk.Frame(root)
        frame.pack()
        self.textPad(frame)
        return

    def textPad(self, frame):
        # add a frame and put a text area into it
        textPad = tk.Frame(frame)
        self.text = tk.Text(textPad, height=18, width=60)
        self.text.config()
        # add a vertical scroll bar to the text area
        scroll = tk.Scrollbar(textPad)
        self.text.configure(yscrollcommand=scroll.set,background="black", foreground="green")
        # pack everything
        self.text.pack(side=tk.LEFT, pady=2)
        scroll.pack(side=tk.RIGHT, fill=tk.Y)
        textPad.pack(side=tk.TOP)
        return

root = tk.Tk()
root.resizable(width=False, height=False)
root.option_add('*font', ('verdana', 9, 'bold'))
app = Application(master=root)
scrollFrame = scrollTxtArea(root)
app.mainloop()

【问题讨论】:

    标签: python tkinter


    【解决方案1】:

    这里有几个问题。

    首先,您使用了错误的几何管理器。包几何管理器,顾名思义,将小部件尽可能紧密地打包在一起。那不是你想要的。网格几何管理器允许您将小部件放入带有行和列的表格布局中。如果您将“浏览”按钮放在第一列,将“退出”按钮放在最后一列,您将更近一步。

    其次,您的Application 窗口包含三个子小部件,您只需将其中两个放入几何管理器。我什至不想去想,这会怎样把你弄得一团糟。所以我将标签放入第 1 列,将退出按钮放入第 2 列,将浏览按钮放入第 0 列。退出按钮我给出了“e”的“粘性”值,因此它将附加到东(右)侧分配的空间。

    第三,所有几何管理器都会尽可能地压缩小部件,除非你明确告诉它不这样做。我告诉网格管理器展开第 2 列,以便将多余的空间分配给包含退出按钮的单元格。

    第四,您需要告诉包管理器展开顶部小部件,使其跨越整个窗口。指令是fill="x"

    第五,您在 createWidgets 函数的末尾有一个对包管理器的冗余调用。

    import tkinter as tk
    from tkinter.ttk import *
    
    class Application(tk.Frame):
        def __init__(self, master=None):
            tk.Frame.__init__(self, master)
            self.pack(fill="x")
            self.createWidgets()
            self.master.title("Log Parser")
        def createWidgets(self):
            self.Run_Main = tk.Button(self)
            self.Run_Main["text"] = "Browse.."
            # self.Run_Main["fg"] = "blue"
            self.Run_Main["command"] = self.Sayhello
            self.Label = tk.Label(self)
            self.Label["text"] = 'Processing...'
            self.progressbar = Progressbar(mode="indeterminate", maximum=20)
            self.QUIT = tk.Button(self)
            self.QUIT["text"] = "Quit!"
            self.QUIT["command"] =  self.quit
            self.Label.grid(row=0, column=1)
            self.Run_Main.grid(row=0, column=0, sticky="w")
            self.QUIT.grid(row=0, column=2, sticky="e")
            self.columnconfigure(2, weight=1)
    
        def Sayhello(self):
           print("Hello")
    
    # scroll text inside application frame
    class scrollTxtArea:
        def __init__(self, root):
            frame = tk.Frame(root)
            frame.pack()
            self.textPad(frame)
            return
    
        def textPad(self, frame):
            # add a frame and put a text area into it
            textPad = tk.Frame(frame)
            self.text = tk.Text(textPad, height=18, width=60)
            self.text.config()
            # add a vertical scroll bar to the text area
            scroll = tk.Scrollbar(textPad)
            self.text.configure(yscrollcommand=scroll.set,background="black", foreground="green")
            # pack everything
            self.text.pack(side=tk.LEFT, pady=2)
            scroll.pack(side=tk.RIGHT, fill=tk.Y)
            textPad.pack(side=tk.TOP)
            return
    
    root = tk.Tk()
    root.resizable(width=False, height=False)
    root.option_add('*font', ('verdana', 9, 'bold'))
    app = Application(master=root)
    scrollFrame = scrollTxtArea(root)
    app.mainloop()
    

    【讨论】:

    • 真正详尽且有用的答案。谢谢
    • “包几何管理器,顾名思义,将小部件尽可能紧密地打包在一起。” - 这是一个有点误导的说法。您可以使用pack,但仍然有相距很远的项目。
    • @BryanOakley 你说得对——我发现网格几何管理器在这些情况下更容易使用,但也许这就是我。
    【解决方案2】:

    这些linklink 提供了帮助。另一种选择是使用 tkinter 的 grid manager,它会更直观,让您在未来更有条理。

    import tkinter as tk
    from tkinter.ttk import *
    
    class Application(tk.Frame):
        def __init__(self, master=None):
            tk.Frame.__init__(self, master)
            self.pack()
            self.createWidgets()
            self.master.title("Log Parser")
        def createWidgets(self):
            self.Run_Main = tk.Button(self)
            self.Run_Main["text"] = "Browse.."
            # self.Run_Main["fg"] = "blue"
            self.Run_Main["command"] = self.Sayhello
            self.Run_Main.pack(side='left')
            self.Label = tk.Label(self)
            self.Label["text"] = 'Processing...'
            self.Label.pack(side='left')
            self.progressbar = Progressbar(mode="indeterminate", maximum=20)
            self.QUIT = tk.Button(self)
            self.QUIT["text"] = "Quit!"
            self.QUIT["command"] =  self.quit
            self.QUIT.pack(side='right')
            self.pack(side="top", fill=tk.BOTH) # changes here
    
        def Sayhello(self):
           print("Hello")
    
    # scroll text inside application frame
    class scrollTxtArea:
        def __init__(self, root):
            frame = tk.Frame(root)
            frame.pack()
            self.textPad(frame)
            return
    
        def textPad(self, frame):
            # add a frame and put a text area into it
            textPad = tk.Frame(frame)
            self.text = tk.Text(textPad, height=18, width=60)
            self.text.config()
            # add a vertical scroll bar to the text area
            scroll = tk.Scrollbar(textPad)
            self.text.configure(yscrollcommand=scroll.set,background="black", foreground="green")
            # pack everything
            self.text.pack(side=tk.LEFT, pady=2)
            scroll.pack(side=tk.RIGHT, fill=tk.Y)
            textPad.pack(side=tk.TOP)
            return
    
    root = tk.Tk()
    root.resizable(width=False, height=False)
    root.option_add('*font', ('verdana', 9, 'bold'))
    app = Application(master=root)
    scrollFrame = scrollTxtArea(root)
    app.mainloop()
    

    【讨论】:

      【解决方案3】:

      您可以进行两个简单的修复以获得所需的行为。

      首先,您需要打包Application 使其填满窗口:

      class Application(...):
          def __init__(...):
              ...
              self.pack(fill="x")
      

      接下来,简单打包窗口右侧的快捷按钮:

      self.QUIT.pack(side="right", anchor='e')
      

      尽管在这个特定示例中您只需要执行上述操作,但您还可以做一些额外的事情来让您的工作更轻松。

      我建议专门为按钮创建一个框架。你可以把它放在顶部。然后,将按钮放在这个框架内,并将它们放在左侧或右侧。您将获得相同的结果,但您会发现稍后添加其他按钮会更容易。

      我还发现,当您将小部件创建与小部件布局分开时,它使代码更易于阅读、编写、维护和可视化。

      class Application(...):
          ...
          def createWidgets(self):
              toolbar = tk.Frame(self)
              toolbar.pack(side="top", fill="x")
      
              self.Run_Main = tk.Button(toolbar)
              self.Label = tk.Label(toolbar)
              self.QUIT = tk.Button(toolbar)
              ...
              self.Run_Main.pack(side="left")
              self.Label.pack(side="left", fill="x")
              self.QUIT.pack(side="right")
              ...
      

      【讨论】:

        猜你喜欢
        • 2018-05-05
        • 2022-10-23
        • 2021-06-15
        • 1970-01-01
        • 2021-01-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-11-21
        相关资源
        最近更新 更多