所以这就是问题所在。我正在使用Python的TKinter编程GUI,我需要窗口是特定的大小。该程序的发布版本将屏幕设置为root.attributes("-fullscreen", True)
,以便全屏显示,用户无法访问任何菜单。所述屏幕将是800x480平板电脑屏幕。
显然我在比800x480大得多的屏幕上编程,所以当我创建我的tkinter窗口时,我设置root.minsize("800x480")
来模拟程序所处的环境。
至于GUI上的内容,我会有一系列按钮和其他东西。窗口本身将分为两个框架:一个按钮框架和一个可视框架。顾名思义,按钮框架将是一个完全由用户输入的按钮组成的框架,而视觉框架显然也只包含用户的视觉输出。
所以这是我的问题。我目前正在处理Button Frame,我遇到的问题是Frame的大小不正确。由于我还没有为Visual Frame完成编程,我只是创建了两个Button Frame并将它们放入根窗口。两个框架都应该占据整个屏幕,但它们不是。这是我的代码:
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个小盒子和一个大的灰色区域。
随机颜色用于测试目的btw:P
编辑:我的代码中有一些复制/粘贴错误,它现在应该作为一个文件工作。道歉。
答案 0 :(得分:4)
您正试图一次解决太多问题。当第一次使用tkinter开始,或者第一次布置新的GUI时,有条不紊并且一次只解决一个布局问题确实很有帮助。
您已选择为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")
看起来这个容器会包含两个孩子,对吗?左侧是按钮框,右侧是主区域。现在让我们使用几个空帧,让它们继续工作。
您没有指定这些区域的大小,因此在此示例中,左侧的列将是屏幕大小的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
和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
属性(minsize,weight,pad)的不同值的好时机,或者切换到使用place
来查看它是如何工作的。
我们只需要继续这个过程,更深层次。好消息是,我们只需关注按钮管理器中发生的事情。除非我们添加一个太大而不适合的小部件,否则我们无法改变整个窗口的整体布局。
看起来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)
这只是一个带有几个标签的框架。同样,由于它只有几个小部件,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")
最后,按钮框架。将有一个按钮网格。到目前为止,该过程应该很熟悉 - 创建小部件,然后使用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。
我知道你需要一个非常特定的大小,但是养成编写符合字体,分辨率和窗口大小变化的guis的习惯是很好的。