gpt4 book ai didi

python - Tkinter:网格或网格内的包?

转载 作者:太空狗 更新时间:2023-10-30 01:50:36 27 4
gpt4 key购买 nike

我正在为软件构建 GUI,并希望实现这一目标:

######################################
# | some title #
# menu upper |----------------------#
# | #
# | CANVAS #
# menu lower | #
# | #
#------------------------------------#
# statusbar #
######################################

Menu upper 具有一些高级功能,menu lower 根据用户输入而变化。状态栏经常更改其内容。


不幸的是,Tkinter 拒绝工作。

使用网格布局管理器我无法创建稳定的设计并向左侧菜单添加标签和按钮等内容:

self.root = tk.Tk()
self.root.resizable(width=0, height=0)
self.root.title("some application")

# menu left
self.menu_left = tk.Frame(self.root, width=150, bg="#ababab")
self.menu_left.grid(row=0, column=0, rowspan=2, sticky="ns")

self.menu_left_upper = tk.Frame(self.menu_left, width=150, height=150, bg="red")
self.menu_left_upper.grid(row=0, column=0)

# this label breaks the design
#self.test = tk.Label(self.menu_left_upper, text="test")
#self.test.pack()

self.menu_left_lower = tk.Frame(self.menu_left, width=150, bg="blue")
self.menu_left_lower.grid(row=1, column=0)

# right area
self.some_title_frame = tk.Frame(self.root, bg="#dfdfdf")
self.some_title_frame.grid(row=0, column=1, sticky="we")

self.some_title = tk.Label(self.some_title_frame, text="some title", bg="#dfdfdf")
self.some_title.pack()

self.canvas_area = tk.Canvas(self.root, width=500, height=400, background="#ffffff")
self.canvas_area.grid(row=1, column=1)

self.root.mainloop()

此设计在左侧菜单中没有内容的情况下工作。每当我在 self.menu_left_upperself.menu_left_lower 中添加一些东西时,比如 test 标签,我的设计就会崩溃:菜单框架消失了。此外,即使使用 columnspan,我也必须删除状态栏,因为当添加它时,左侧的菜单再次消失。


使用包布局管理器我得到了这个:

######################################
# | some title #
# |----------------------#
# menu upper | #
# | CANVAS #
# | #
# menu lower | #
# |----------------------#
# | statusbar #
######################################

因为我想让左边的菜单框架占用整个 y 空间,所以我用 pack(side="left", expand=True, fill="both") 让它变大,但是这个设置总是拒绝状态栏去全宽。

此外,纯包管理器代码看起来“丑陋”。我认为带有网格管理器的设计“更清晰”。因此我认为网格或网格布局中的包布局会很好


有人可以帮忙吗?我陷入了 GUI hell :/

最佳答案

布局的关键是要有条不紊,并使用正确的工具为了工作。这也意味着有时您需要发挥创造力。这意味着在布局时使用 gridgrid,并在自上而下布局时使用 pack 或左到右。

另一个关键是将布局代码组合在一起。很多很多当所有内容都在一个 block 中时,更容易可视化和修改布局代码。

在您的情况下,您似乎有三个或四个不同的区域,具体取决于关于你如何计算。如果你想使用 grid,最简单的方法是将“菜单上层”和“菜单下层”组合成一个框架,然后对待它整个框架作为表格单元格。看起来你已经在这样做了,这很好。

那么,让我们从这些主要领域开始:

self.menu_left.grid(row=0, column=0, rowspan=2, sticky="nsew")
self.some_title_frame.grid(row=0, column=1, sticky="ew")
self.canvas_area.grid(row=1, column=1, sticky="nsew")
# you don't have a status bar in the example code, but if you
# did, this is where you would put it
# self.status_frame.grid(row=2, column=0, columnspan=2, sticky="ew")

任何时候你使用grid,你需要至少给出一行和一个列一个正权重,以便 tkinter 知道在哪里使用任何未分配的空间。通常有一个小部件是“主要”小部件。在这种情况下,它是 Canvas 。你想确保 Canvas 的行和列的权重为 1(一):

self.root.grid_rowconfigure(1, weight=1)
self.root.grid_columnconfigure(1, weight=1)

注意:使用 pack 而不是 grid 会为您节省两行代码,因为 pack 不需要您设置权重grid 的方式。

接下来,我们需要解决菜单区域的问题。默认情况下,框架缩小以适合其内容,这就是添加标签的原因打破了你的布局。你没有告诉 tkinter 如何处理额外的空间,因此框架缩小以适合,额外的空间未被使用。

因为你想要“menu_upper”和“menu_lower”每个共享该区域的 50%,pack 是最简单的解决方案。你可以使用 grid,但它需要更多的代码行来添加行和列的权重。

self.menu_left_upper.pack(side="top", fill="both", expand=True)
self.menu_left_lower.pack(side="top", fill="both", expand=True)

这是一个功能版本,带有状态栏。当您调整窗口大小时,请注意它的行为与应有的完全一致:

import Tkinter as tk

class Example():
def __init__(self):
self.root = tk.Tk()
self.root.title("some application")

# menu left
self.menu_left = tk.Frame(self.root, width=150, bg="#ababab")
self.menu_left_upper = tk.Frame(self.menu_left, width=150, height=150, bg="red")
self.menu_left_lower = tk.Frame(self.menu_left, width=150, bg="blue")

self.test = tk.Label(self.menu_left_upper, text="test")
self.test.pack()

self.menu_left_upper.pack(side="top", fill="both", expand=True)
self.menu_left_lower.pack(side="top", fill="both", expand=True)

# right area
self.some_title_frame = tk.Frame(self.root, bg="#dfdfdf")

self.some_title = tk.Label(self.some_title_frame, text="some title", bg="#dfdfdf")
self.some_title.pack()

self.canvas_area = tk.Canvas(self.root, width=500, height=400, background="#ffffff")
self.canvas_area.grid(row=1, column=1)

# status bar
self.status_frame = tk.Frame(self.root)
self.status = tk.Label(self.status_frame, text="this is the status bar")
self.status.pack(fill="both", expand=True)

self.menu_left.grid(row=0, column=0, rowspan=2, sticky="nsew")
self.some_title_frame.grid(row=0, column=1, sticky="ew")
self.canvas_area.grid(row=1, column=1, sticky="nsew")
self.status_frame.grid(row=2, column=0, columnspan=2, sticky="ew")

self.root.grid_rowconfigure(1, weight=1)
self.root.grid_columnconfigure(1, weight=1)

self.root.mainloop()

Example()

一个不相关的说明:我强烈建议您不要删除用户调整窗口大小的功能。他们比你更清楚他们的要求是什么。如果您正确使用 gridpack,GUI 将完美地调整大小。

关于python - Tkinter:网格或网格内的包?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36506152/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com