如何创建一个可调整大小的窗口,包括侧边栏和内容区域?

7 投票
1 回答
5367 浏览
提问于 2025-04-17 21:22

我正在用Python和Tkinter做一些很常见的图形界面设计,但遇到了一些问题。我想做一个像下面这样的布局:

+------+----------------------+
|      |                      |
|      |                      |
|      |                      |
|      |                      |
|      |                      |
|      |                      |
|      |                      |
|      |                      |
|      |                      |
|      |                      |
|      |                      |
|      |                      |
|      |                      |
|      |                      |
+------+----------------------+

这个布局很简单,有一个侧边栏和一个主要内容区域。我可以很顺利地摆放这些框架,但问题出现在我想要调整窗口大小的时候。我可以让侧边栏在垂直方向上正常调整大小,但在水平方向上却不行,它一直固定在左边。而主要内容区域却不愿意填充剩下的水平空间。就好像侧边栏在水平方向上占据的空间没有变化,即使它被设置为只在y方向上调整大小。

这里有一些很简单的代码来演示我的意思:

from Tkinter import *

root = Tk()

# sidebar
sidebar = Frame(root, width=200, bg='white', height=500, relief='sunken', borderwidth=2)
sidebar.pack(expand=True, fill='y', side='left', anchor='nw')

# main content area
mainarea = Frame(root, bg='#CCC', width=500, height=500)
mainarea.pack(expand=True, fill='both', side='right')

root.mainloop()

然后这是我尝试调整大小时发生的情况:

不正确的调整大小布局

有没有什么想法?我觉得这个应该是可以做到的,对吧?这几乎是个标准的布局。

1 个回答

8

简而言之:给侧边栏使用 fill="both"

问题概述

你看到的额外空间是属于侧边栏的。因为你对两个小部件都使用了 expand=true,所以当你调整窗口大小时,它们各自会获得一部分额外的空间。由于你没有为侧边栏指定在“x”方向上的 fill,所以它获得了一些额外的空间,但并没有填满。它在“y”方向上是填满的,正如你所要求的,而主区域则完全填满了它的空间,因为它有 fill="both"

你需要让侧边栏在“x”和“y”两个方向上都填满,或者关闭扩展功能,让它保持固定大小。注意:当我说“固定大小”时,如果你使用 fill=both,它仍然会填满分配给它的区域,但当你调整窗口大小时,所有的额外空间都会分配给主窗口。

使用固定大小的侧边栏

要让侧边栏保持固定大小,关闭扩展功能 off,但将填充设置为 both。你希望它填满分配给它的区域,但不希望这个区域在窗口变大时也跟着变大:

import Tkinter as tk

root = tk.Tk()

# sidebar
sidebar = tk.Frame(root, width=200, bg='white', height=500, relief='sunken', borderwidth=2)
sidebar.pack(expand=False, fill='both', side='left', anchor='nw')

# main content area
mainarea = tk.Frame(root, bg='#CCC', width=500, height=500)
mainarea.pack(expand=True, fill='both', side='right')

root.mainloop()

使用可扩展的侧边栏

要让侧边栏的大小灵活,打开扩展功能 on,这样在你调整窗口大小时,它就会获得一部分额外的空间。你希望填充设置为 both,这样它就能填满分配给它的空间。

import Tkinter as tk

root = tk.Tk()

# sidebar
sidebar = tk.Frame(root, width=200, bg='white', height=500, relief='sunken', borderwidth=2)
sidebar.pack(expand=True, fill='both', side='left', anchor='nw')

# main content area
mainarea = tk.Frame(root, bg='#CCC', width=500, height=500)
mainarea.pack(expand=True, fill='both', side='right')

root.mainloop()

总结

这两个例子之间唯一的区别就是使用了 expand=True 还是 expand=False。扩展功能控制窗口调整大小时额外空间的分配。当设置为真时,额外空间会分配给这个小部件,以及其他设置为真扩展的部件。然而,在 两种情况下,你都希望侧边栏完全填满它所占据的区域。所以在这两种情况下,你都希望使用 fill="both"。填充只决定小部件如何处理它所占据的区域(填满或不填满),但并不影响小部件请求的空间是否增多或减少。

  • expand:窗口调整大小时,是否给小部件分配更多空间
  • fill:小部件是否填满它所占据的空间,或者是否留有空白部分

撰写回答