如何使用 grid() 将小部件水平居中?

Posted

技术标签:

【中文标题】如何使用 grid() 将小部件水平居中?【英文标题】:How to horizontally center a widget using grid()? 【发布时间】:2016-01-07 21:43:57 【问题描述】:

我正在使用grid() 将小部件放置在 tkinter 窗口中。我试图在窗口的水平中心放置一个标签并让它保持在那里,即使窗口已调整大小。我该怎么做呢?

顺便说一句,我不想​​使用pack()。我想继续使用grid()

【问题讨论】:

【参考方案1】:

没有什么技巧——默认情况下,小部件位于分配给它的区域的中心。只需在没有任何sticky 属性的单元格中放置一个标签,它就会居中。

现在,另一个问题是,如何让分配的区域居中。这取决于许多其他因素,例如还有哪些其他小部件、它们的排列方式等。

这是一个显示单个居中标签的简单示例。它通过确保它所在的行和列占用所有额外空间来做到这一点。请注意,无论窗口有多大,标签都会保持居中。

import Tkinter as tk

class Example(tk.Frame):
    def __init__(self, parent):
        tk.Frame.__init__(self, parent)
        label = tk.Label(self, text="This should be centered")
        label.grid(row=1, column=1)
        self.grid_rowconfigure(1, weight=1)
        self.grid_columnconfigure(1, weight=1)

if __name__ == "__main__":
    root = tk.Tk()
    Example(root).grid(sticky="nsew")
    root.grid_rowconfigure(0, weight=1)
    root.grid_columnconfigure(0, weight=1)
    root.mainloop()

您可以通过为所有行和列赋予权重来获得类似的效果除了带有标签的行和列。

import Tkinter as tk

class Example(tk.Frame):
    def __init__(self, parent):
        tk.Frame.__init__(self, parent)
        label = tk.Label(self, text="This should be centered")
        label.grid(row=1, column=1)

        self.grid_rowconfigure(0, weight=1)
        self.grid_rowconfigure(2, weight=1)
        self.grid_columnconfigure(0, weight=1)
        self.grid_columnconfigure(2, weight=1)

if __name__ == "__main__":
    root = tk.Tk()
    Example(root).grid(sticky="nsew")
    root.grid_rowconfigure(0, weight=1)
    root.grid_columnconfigure(0, weight=1)

    root.mainloop()

【讨论】:

这看起来非常复杂。此外,它使用包。我只想使用网格,因为其他小部件必须使用网格。 @Legodog5678:它使用 pack 的事实无关紧要。它仅使用 pack 作为示例周围的样板。它可以很容易地网格化。如果这让你更舒服,我会改变它。在没有看到您的实际代码的情况下,我不能让它变得不那么复杂——第一个示例只需要三行代码,其余代码只是样板文件。修复您的特定代码可能只是添加行和列权重的问题——grid 需要的额外步骤,pack 不需要。 只要给出现标签的行和列的权重1,一定不要指定sticky属性。默认情况下,行和列的权重设置为零,这意味着两者都不会增长以填充小部件中的任何额外空间。将其设置为 1 意味着它将填充该空间并随着用户扩展窗口而线性增长。正如 Bryan 所提到的,这是使用网格时所必需的额外步骤,而使用 pack 时则不需要。【参考方案2】:

没有什么特别的要求。小部件将自动位于其父级的中间。告诉父母填满所有可用空间需要什么。

from tkinter import *
root = Tk()
root.geometry("500x500+0+0")
frmMain = Frame(root,bg="blue")

startbutton = Button(frmMain, text="Start",height=1,width=4)
startbutton.grid()

#Configure the row/col of our frame and root window to be resizable and fill all available space
frmMain.grid(row=0, column=0, sticky="NESW")
frmMain.grid_rowconfigure(0, weight=1)
frmMain.grid_columnconfigure(0, weight=1)
root.grid_rowconfigure(0, weight=1)
root.grid_columnconfigure(0, weight=1)

root.mainloop()

这使用网格而不是打包来放置小部件,并且网格被配置为填充窗口的整个大小。无论窗口大小,按钮都会出现在中间。

【讨论】:

好像只有一行一列,有没有办法让它多列多行?【参考方案3】:

这对我有用:

    lbl1 = Label(self, text='some text')     
    lbl1.grid(row=1, column=1, sticky='e')  # right aligned
    # sticky='w'  # left aligned
    # sticky=''  # centered (or no sticky)

【讨论】:

【参考方案4】:

还有另一种方法,虽然不是.grid,但它是.place。我发现当使用.gridsticky 居中时,如果您只使用一列,则小部件不会居中。

label1 = Label(loginWindow, text="Please Log In", font=("Arial", 25))
label1.place(anchor = CENTER, relx = .5, rely = .2)

其中relxrely 是它所在屏幕的百分比,anchor=CENTER 是所有小部件的中心。

【讨论】:

以上是关于如何使用 grid() 将小部件水平居中?的主要内容,如果未能解决你的问题,请参考以下文章

如何将小部件添加到 Dojo gridx/Grid 标题?

如何在垂直 Gtk.Box 内水平居中 Gtk.Grid?

Gridstack:将小部件从一个网格拖到另一个网格中,嵌套一个

Gridstack:将小部件从一个网格拖动到另一个网格,嵌套一个

如何使用 PyQt 中的样式表将小部件放在前面?

在 Bootstrap Grid 中垂直和水平居中图像