所以问题来了。我正在使用 Python 的 TKinter 对 GUI 进行编程,并且我需要将窗口设为特定大小。该程序的发布版本将具有 root.attributes("-fullscreen", True)
的屏幕设置所以它是全屏的,用户将无法访问任何菜单。所述屏幕将是 800x480 平板电脑屏幕。
显然我在比 800x480 大得多的屏幕上编程,所以当我创建我的 tkinter 窗口时,我正在设置 root.minsize("800x480")
模拟程序所处的环境。
至于 GUI 上有什么,我会有一系列按钮和其他东西。窗口本身将被分成两个框架:按钮框架和视觉框架。按钮框架,顾名思义,将是一个完全由用于用户输入的按钮组成的框架,而视觉框架,同样显然,将只包含用户的视觉输出。
所以这是我的问题。我目前正在处理 Button Frame,但我遇到了 Frame 尺寸不正确的问题。由于我还没有完成 Visual Frame 的编程,我刚刚创建了两个 Button Frames 并将它们放置到根窗口中。两个框架都应该占据整个屏幕,但它们不是。这是我的代码:
import tkinter as tk
from tkinter import ttk
class ButtonManager(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.config(background = 'green')
self.columnconfigure(0, weight = 1)
self.rowconfigure(0, weight = 1)
lblFrame = LabelFrame(self, controller)
lblFrame.grid(column = 0, row = 0, sticky = "nsew")
lblFrame.tkraise()
btnFrame = ButtonFrame(self, controller)
btnFrame.grid(column = 0, row = 1, sticky = "nsew")
btnFrame.tkraise()
for child in self.winfo_children():
child.grid_configure(padx = 5, pady = 5)
class LabelFrame(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.config(background = 'blue')
lblTitleBar = ttk.Label(self, text = 'TITLE BAR', background = 'grey', font = ("Arial", 20, "bold"))
lblTitleBar.grid(column = 1, row = 1, columnspan = 4, sticky = "nsew")
lblTextBar = ttk.Label(self, text = 'test text', background = 'grey', font = ("Arial", 16, "bold"))
lblTextBar.grid(column = 1, row = 2, columnspan = 4, sticky = "nsew")
class ButtonFrame(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.config(background = 'red')
btn1 = ttk.Button(self, text = '1', command = lambda : print("1"))
btn1.grid(column = 1, row = 1, columnspan = 2, rowspan = 2, sticky = "nsew")
#Not gonna type out the code for all the buttons, but I have 2 columns, and 6 rows.
#The buttons on the 4th and 6th row span the columns of both rows.
#In total there are 10 buttons
for child in self.winfo_children():
child.grid_configure(padx = 5, pady = 5)
class Interface(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
container = tk.Frame(self)
container.grid(column = 0, row = 0, sticky = "nsew")
container.grid_rowconfigure(0, weight = 1)
container.grid_columnconfigure(0, weight = 1)
bMan1 = ButtonManager(container, self)
bMan1.grid(column = 0, row = 0, sticky = "nsew")
bMan2 = ButtonManager(container, self)
bMan2.grid(column = 1, row = 0, sticky = "nsew")
interface = Interface()
interface.minsize(800, 480)
interface.mainloop()
正如我上面所说,我的问题是我需要每个 ButtonManager 对象在每个宽度上占据屏幕的一半。然而,我得到了 2 个小盒子和一个大的灰色区域。
随机颜色用于测试目的顺便说一句:P
编辑:我的代码中有一些复制/粘贴错误,现在它应该可以作为单个文件工作。道歉。
最佳答案
你试图一次解决太多问题。当第一次开始使用 tkinter 时,或者当第一次布局一个新的 GUI 时,有条不紊地一次只解决一个布局问题真的很有帮助。
第 1 步 - 主窗口
您已选择为 GUI 中的所有内容创建一个“容器”。因此,第一步是在尝试让其他任何事情发挥作用之前先让其发挥作用。如果它太小,那么它会导致它里面的所有东西都太小,这就是原始代码问题的一部分。
由于它是根目录中唯一的小部件,我建议使用 pack
.您可以使用 grid
,但这需要三行代码而不是一行,因为使用 grid
您必须记住配置至少一行和一列的权重。
从以下内容开始(并且仅以下内容):
class Interface(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
container = tk.Frame(self, background="bisque")
container.pack(fill="both", expand=True)
interface = Interface()
interface.minsize(800, 480)
interface.mainloop()
它看起来如何?对我来说看起来不错——蓝色完全填满了 800x480 的窗口。我们现在不再需要担心容器。
如果您想使用
grid
, 删除调用 pack
的一行,并将其替换为以下三行:self.grid_rowconfigure(0, weight=1)
self.grid_columnconfigure(0, weight=1)
container.grid(row=0, column=0, sticky="nsew")
第 2 步 - 容器的 child
看起来容器将包含两个 child ,对吗?左侧为按钮框,右侧为主要区域。现在让我们使用几个空框架,并在继续之前让它们工作。
您没有指定这些区域的大小,因此在此示例中,左侧的列将是屏幕大小的 1/3,右侧的列将是 2/3。如果您愿意,您可以为左侧使用固定的像素宽度,而让右侧占据其余部分。
如果你需要一个非常具体的宽度,你可以使用
place
在这里,但现在我们将坚持使用 grid
.将以下内容添加到
Interface.__init__
的底部: bman = ButtonManager(container, controller=self)
main = Main(container, controller=self)
container.grid_columnconfigure(0, weight=1)
container.grid_columnconfigure(1, weight=2)
container.grid_rowconfigure(0, weight=1)
bman.grid(row=0, column=0, sticky="nsew")
main.grid(row=0, column=1, sticky="nsew")
我们还需要为
ButtonManager
定义 stub 和 Main
:class ButtonManager(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
self.configure(background="green")
class Main(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
self.configure(background="yellow")
编码就够了。停止并运行代码,确保粉色窗口占据蓝色区域的 1/3,黄色窗口占据另外 2/3。
这可能是使用
columnconfigure
的不同值的好时机。属性(最小尺寸、重量、填充),或切换到使用 place
看看它是如何工作的。第 3 步 - 按钮管理器
我们只需要继续这个过程,再深入一层。好消息是,我们只需要关注按钮管理器内部发生的事情。除非我们添加一个太大而无法容纳的小部件,否则我们无法整体更改窗口的整体布局。
它看起来像
ButtonManager
由标题和按钮区域组成。所以,让我们补充一下。由于这个框架中只有两个小部件,我们可以再次使用 pack
来节省几行代码和一些麻烦。 ,因为 pack 擅长从上到下堆叠东西。在下面的代码中,我将标签贴在顶部,并让按钮框填充窗口的其余部分。
更改
ButtonManager
看起来像这样:class ButtonManager(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
self.config(background = 'green')
lblFrame = LabelFrame(self, controller)
btnFrame = ButtonFrame(self, controller)
lblFrame.pack(side="top", fill="x", expand=False)
btnFrame.pack(side="top", fill="both", expand=True)
第 4 步:标签框架
这只是一个带有几个标签的框架。同样,由于它只有几个小部件,
pack
将节省一点编码。您可以使用 grid
如果需要,请记住您必须配置行和列的权重。class LabelFrame(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
self.configure(background="blue")
lblTitleBar = ttk.Label(self, text = 'TITLE BAR', background = 'grey', font = ("Arial", 20, "bold"))
lblTextBar = ttk.Label(self, text = 'test text', background = 'grey', font = ("Arial", 16, "bold"))
lblTitleBar.pack(side="top", fill="x")
lblTextBar.pack(side="top", fill="x")
第 5 步 - ButtonFrame
最后,按钮框架。将有一个按钮网格。现在这个过程应该很熟悉了 - 创建小部件,并使用
grid
或 pack
把它们摆出来。在这种情况下 grid
最有意义。class ButtonFrame(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
self.configure(background="red")
for row in range(7):
self.grid_rowconfigure(row, weight=1)
self.grid_columnconfigure(0, weight=1)
self.grid_columnconfigure(1, weight=1)
b1 = tk.Button(self, text="Button 1")
b2 = tk.Button(self, text="Button 2")
b3 = tk.Button(self, text="Button 3")
b4 = tk.Button(self, text="Button 4")
b5 = tk.Button(self, text="Button 5")
b6 = tk.Button(self, text="Button 6")
b7 = tk.Button(self, text="Button 7")
b8 = tk.Button(self, text="Button 8")
b9 = tk.Button(self, text="Button 9")
b10 = tk.Button(self, text="Button 10")
b1.grid(row=0, column=0, sticky="nsew")
b2.grid(row=0, column=1, sticky="nsew")
b3.grid(row=1, column=0, sticky="nsew")
b4.grid(row=1, column=1, sticky="nsew")
b5.grid(row=2, column=0, sticky="nsew")
b6.grid(row=2, column=1, sticky="nsew")
b7.grid(row=3, column=0, columnspan=2, sticky="nsew")
b8.grid(row=4, column=0, sticky="nsew")
b9.grid(row=4, column=1, sticky="nsew")
b10.grid(row=5, column=0, columnspan=2, sticky="nsew")
概括
如果您对 GUI 布局采用有条理的方法,那么问题将变得更容易解决,因为您一次只解决一个区域。如果您严格遵循上述所有内容,您最终会得到一个 GUI,即使您扩大或缩小窗口,它也能很好地工作。
我知道您需要一个非常具体的尺寸,但是养成编写 gui 的习惯是很好的,这些 gui 可以响应字体、分辨率和窗口尺寸的变化。
关于python - TKinter GUI,如何使帧的大小正确?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44830919/