使用 Tkinter 的按钮布局?

Button Layout with Tkinter?

我想让我的按钮成为 window 底部的 2 x 2 网格,上面有 canvas 但是当我使用 .pack(side = 随便)。

重要的是,我还希望按钮和 canvas 具有相对大小,即 %,以便无论何时调整 window 的大小时,按钮仍然构成正确的区域。

作为 tkinter 的新手,我不确定该怎么做,感谢您的帮助。

   import tkinter
from tkinter import *

code = Tk()

def LAttack():
    print(something);
def HAttack():
    print(something);
def FField():
    print(something);
def Heal():
    print(something);
def Restart():
    print(something);

Attack1 = tkinter.Button(code,text = ("Light Attack"), command = LAttack)
Attack1.pack(side = LEFT)
Attack2 = tkinter.Button(code,text = ("Heavy Attack"), command = HAttack)
Attack2.pack(side = RIGHT)
Defense1 = tkinter.Button(code,text = ("Forcefield"), command = FField)
Defense1.pack(side = LEFT)
Defense2 = tkinter.Button(code,text = ("Heal"), command = Heal)
Defense2.pack(side = RIGHT)
Restart1 = tkinter.Button(code,text = ("Restart"), command = Restart)
Restart1.pack(side = TOP)

code.mainloop()

但我希望它看起来像这样: Mock up for GUI

I want to make my buttons a 2 x 2 grid on the bottom of the window with a canvas above them but the buttons always seem to stack weird when I use .pack(side = whatever).

对我来说,这意味着您显然需要关注两个独立的区域:带有 canvas 的顶部区域和带有按钮的底部区域。第一步是创建这两个区域。顶部只需使用 canvas,底部使用框架。

我假设您希望 canvas 占据尽可能多的 space,按钮始终位于底部。对于这种安排,pack 最有意义。

下面给了我们一个程序,上面有一个canvas,底部有一个框架来固定按钮。当您调整 window 的大小时,按钮框架保留在底部,canvas 填充 space:

的其余部分
import tkinter as tk

root = tk.Tk()

canvas = tk.Canvas(root, background="white")
button_frame = tk.Frame(root)

button_frame.pack(side="bottom", fill="x", expand=False)
canvas.pack(side="top", fill="both", expand=True)

# <button code will be added here...>

root.mainloop()

现在我们可以专注于按钮。你想要 2x2 网格中的按钮(虽然你有 5 个按钮......?),所以自然的选择是使用 grid 而不是 pack。我们希望这些按钮位于底部框架中,因此我们将该框架作为按钮的父级或主框架。

你也有点好奇地写了"whenever the window is resized the buttons still make up the right area",尽管你之前说你想要它们在底部。我假设您的意思是希望它们位于右下角。

为此,我们将创建一个包含两行和 列的网格。左边的列将是空的,它会占用任何额外的space来强制按钮在右边(当然,如果你愿意,你可以把东西放在这个列中)

这将创建四个按钮:

attack1 = tk.Button(button_frame, text="Light Attack")
attack2 = tk.Button(button_frame, text="Heavy Attack")
defense1 = tk.Button(button_frame, text="Forcefield")
defense2 = tk.Button(button_frame, text="Heal")

...这会导致第一列扩展以填充任何额外的 space:

button_frame.grid_columnconfigure(0, weight=1)

...这会将它们布置在网格中(将小部件创建与小部件布局分开总是好的,因为这样可以更容易地在代码中可视化布局)

attack1.grid(row=0, column=1, sticky="ew")
attack2.grid(row=0, column=2, sticky="ew")
defense1.grid(row=1, column=1, sticky="ew")
defense2.grid(row=1, column=2, sticky="ew")

最终结果是这样的:

调整大小时,按钮保持其相对位置:

总结

这样做的目的是表明您需要花几分钟时间将屏幕上的项目组织成逻辑组。有不同的布局工具可解决不同的问题(gridpackplace),大多数 windows 将受益于针对您遇到的每种类型的布局问题使用正确的工具我正在尝试解决(pack 适用于水平和垂直布局,grid 适用于网格,place 涵盖了一些需要像素完美控制的边缘情况)。