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

24

我正在使用grid()在tkinter窗口中放置控件。我想把一个标签放在窗口的水平中心,并使其保持在那里,即使窗口被调整大小。我该如何做?

顺便说一下,我不想使用pack(),我希望继续使用grid()

4个回答

25

没有什么诀窍——小部件默认情况下是在分配给它的区域居中的。只需将标签放置在没有任何 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()

这看起来非常复杂。而且它使用了pack。我只想使用grid,因为其他小部件必须使用grid。 - L4undry
@Legodog5678:它使用pack的事实是无关紧要的。它只是在示例周围使用pack来生成样板代码。同样可以使用grid。如果这样做让您感到更舒适,我会进行更改。我无法使它更简单,因为我没有看到您的实际代码--第一个示例只需要三行代码,其余代码只是样板代码。要修复您的特定代码可能只需要添加行和列权重--这是grid需要但pack不需要的额外步骤。 - Bryan Oakley
2
只需将标签出现的行和列赋予权重1,确保不指定粘性属性。默认情况下,行和列的权重设置为零,这意味着它们都不会在小部件中填充任何额外的空间。将其设置为1意味着它将填充该空间,并随着用户扩展窗口而线性增长。正如Bryan所提到的,这是使用网格时需要的额外步骤,在使用pack时不需要。 - Daniel Kocevski

4

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

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

这里使用 grid 而不是 pack 来放置小部件,并且将网格配置为填充整个窗口大小。无论窗口大小如何,按钮都会显示在中心位置。


似乎只有一行和一列,有没有办法让它拥有多行和多列? - Zany_Zachary1

2
这对我有用:
    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)

1

虽然不是使用.grid,但还有另一种方法:.place。我发现,如果只使用一列的话,当使用.gridsticky进行居中对齐时,小部件无法居中对齐。

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

relxrely表示控件在屏幕上的位置百分比,anchor=CENTER可以使所有控件居中显示。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接