【问题标题】:How to align widgets in a grid with tkinter?如何使用 tkinter 对齐网格中的小部件?
【发布时间】:2019-03-01 15:22:59
【问题描述】:

我试图将窗口中心的标签与它下面的两个按钮对齐,也居中。我一直在谷歌搜索并在这里寻找如何做到这一点,我发现网格很有帮助,但它并没有达到我的预期。如果我将每个小部件放在不同的行和列中,它会像我预期的那样工作,但是如果我将它们放在不同的行和同一列中,它们只会保持左对齐。我在网格上做错了什么?此外,任何关于我如何改进整体代码的建议都将不胜感激。

我忽略了 LoadedMachine 和 CreateMachine 类,因为我觉得它们不是必需的。如果它们有帮助,我可以编辑问题以添加它们。

class App(tk.Tk):

    def __init__(self, *args, **kwargs):
        tk.Tk.__init__(self, *args, **kwargs)
        container = tk.Frame(self)
        container.pack(side='top', fill='both', expand=True)

        self.frames = {}

        for F in (StartPage, LoadedMachine, CreateMachine):
            page_name = F.__name__
            frame = F(parent=container, controller=self)
            self.frames[page_name] = frame
            frame.grid(row=0, column=0)
            frame.config(bg='white')

        self.show_frame('StartPage')

    def show_frame(self, page_name):
        frame = self.frames[page_name]
        frame.tkraise()


class StartPage(tk.Frame):

    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        self.controller = controller
        self.rowconfigure(0, weight=1)
        self.rowconfigure(1, weight=1)
        self.rowconfigure(2, weight=1)
        self.columnconfigure(0, weight=1)
        self.columnconfigure(1, weight=1)
        self.columnconfigure(2, weight=1)

        welcome_label = tk.Label(self, text='Welcome', bg='green', fg='white', font=('Verdana', 80))
        welcome_label.grid(row=0, column=1)

        loadButton = tk.Button(self, text='Load an existing state machine', command=lambda: controller.show_frame('LoadedMachine'))
        loadButton.config(highlightbackground='green', font=('Verdana', 18))
        loadButton.grid(row=1, column=1)

        createButton = tk.Button(self, text='Create a new state machine', command=lambda: controller.show_frame('CreateMachine'))
        createButton.config(highlightbackground='green', font=('Verdana', 18))
        createButton.grid(row=2, column=1)    


if __name__ == '__main__':
app = App()
app.title('Cognitive State Machine')
app.geometry('800x600')
app.mainloop()

这是我得到的:

我希望按钮靠得更近,更靠近标签。

【问题讨论】:

  • 看起来你也给行一个weight - 你不必这样做。
  • 啊,明白了。谢谢你解决了我的问题。

标签: python-3.x tkinter widget tkinter-layout


【解决方案1】:

一个建议是在创建框架时首先添加一些背景颜色以进行故障排除。

class App(tk.Tk):

    def __init__(self, *args, **kwargs):
        tk.Tk.__init__(self, *args, **kwargs)
        container = tk.Frame(self,bg="yellow")
        container.pack(side='top', fill='both', expand=True)
        container.grid_rowconfigure(0, weight=1)
        container.grid_columnconfigure(0, weight=1)
        ...

当你运行它时,你会看到一堆黄色,这意味着你的StartPage 框架没有填满空间。所以你需要改变它:

for F in (StartPage,):
        page_name = F.__name__
        frame = F(parent=container, controller=self)
        self.frames[page_name] = frame
        frame.grid(row=0,column=0,sticky="nesw")
        frame.config(bg='green')

现在您可以看到您的背景变为绿色,这意味着您的 StartPage 框架正确缩放。最后,您可以处理标签:

def __init__(self, parent, controller):
    tk.Frame.__init__(self, parent)
    self.controller = controller
    self.columnconfigure(0, weight=1)
    ...

关于为什么需要为列添加权重,有一篇很棒的帖子 here

【讨论】:

  • 谢谢这帮助了很多人。除了在 for F in (StartPage,): 循环中,如果我将其更改为 frame.pack(fill='both', expand=True),它会显示所有帧的所有内容,而无需按下按钮实际切换到另一个框架。我该如何解决这个问题?
  • 如果没有其他两页,我不确定您希望您的框架如何显示。但是您也可以使用grid 并为您的框架设置相应的权重。
  • 我想在单击 loadButton 或 createButton 时完全切换框架,并且只显示该框架上的小部件。
  • 我已经编辑了答案。在这种情况下,您还需要在 container 框架上设置 weight
  • 太棒了,我真的很感激!像魅力一样工作。
【解决方案2】:

向网格添加填充以按照您的需要对齐

您可以根据需要添加padx或pady

loadButton.grid(row=1, column=1, padx=10, pady=20)

Helpfull link to further play with grid layout

您也可以使用“部分”来代替“lambda”,因为我们需要从命令函数中调用该函数并在那里定义它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-05
    • 1970-01-01
    • 2018-05-07
    • 2019-06-04
    • 2018-05-26
    • 2014-04-28
    相关资源
    最近更新 更多