
本文详解如何将 `ttk.notebook` 正确添加到 `tk.frame` 中,包括实例化、布局管理及标签页(tab)的创建与配置,确保 notebook 在父容器中自适应显示。
在 Tkinter 中,ttk.Notebook 是一个标准的容器控件,其使用方式与其他 ttk 或 tk 组件完全一致:先创建实例,再通过 pack/grid/place 布局到父容器中,最后调用 .add() 方法添加子页(Frame)。常见误区是仅创建 Notebook 而未显式布局,或忽略其内部 Tab 页必须为 Frame(或其他兼容容器)并需正确挂载。
以下是在您原有 MyApp 类中集成 Notebook 的完整改造示例(基于 grid 布局,兼顾可扩展性与响应式):
import tkinter as tk
from tkinter import ttk
class MyApp(tk.Tk):
def __init__(self):
super().__init__()
self.title("hello world")
# 创建两个主 Frame
self.frame0 = tk.Frame(self, background="green")
self.frame1 = tk.Frame(self, background="blue")
self.frame0.pack(side="top", fill="both", expand=True)
self.frame1.pack(side="top", fill=tk.X, expand=True)
# 在 frame0 中添加 Notebook(使用 grid 实现灵活布局)
self.tabControl = ttk.Notebook(self.frame0)
self.tabControl.grid(row=0, column=0, sticky="nsew", padx=2, pady=2)
# 配置 frame0 的 grid 权重,使 Notebook 可随窗口缩放
self.frame0.grid_rowconfigure(0, weight=1)
self.frame0.grid_columnconfigure(0, weight=1)
# 创建并添加 Tab 页(每个 Tab 必须是独立 Frame)
self.tab1 = tk.Frame(self.tabControl, background="#f0f0f0")
self.tab2 = tk.Frame(self.tabControl, background="#e0e0e0")
self.tabControl.add(self.tab1, text="Tab 0")
self.tabControl.add(self.tab2, text="Tab 1")
# 可选:在 Tab 内添加内容(如 Label)
tk.Label(self.tab1, text="Content of Tab 0", font=("Arial", 10)).pack(pady=20)
tk.Label(self.tab2, text="Content of Tab 1", font=("Arial", 10)).pack(pady=20)
# frame1 保持不变
self.frame1_label0 = tk.Label(self.frame1, text="OTHER")
self.frame1_label0.grid(row=0, column=0)
def main():
app = MyApp()
app.minsize(480, 320) # 设置最小尺寸,避免 Notebook 被压缩
app.mainloop()
if __name__ == "__main__":
main()✅ 关键要点说明:
- 布局不可省略:ttk.Notebook(self.frame0) 仅创建对象,必须配合 grid() / pack() 才能显示;此处推荐 grid(),便于与 frame0 的网格权重协同控制伸缩行为。
- 权重配置至关重要:通过 frame0.grid_rowconfigure(0, weight=1) 和 grid_columnconfigure(0, weight=1),确保 Notebook 占满可用空间。
- Tab 页必须是容器组件:tk.Frame 是最常用且安全的选择;避免直接传入 Label 或 StringVar 等非容器对象。
- 注意嵌套层级:Notebook → Tab Frame → 子控件,每一层都需独立布局(如 tab1 内部仍需 pack/grid)。
⚠️ 注意事项:
- 若使用 pack() 布局 Notebook,请确保 frame0 未启用 grid 混合布局(Tkinter 不支持同一容器内混用 pack 与 grid);
- Notebook 默认不自动拉伸子页,需在每个 Tab Frame 内部合理设置其子控件的 sticky 或 fill 属性;
- 如需动态增删 Tab,可使用 .add()、.forget()、.insert() 和 .select() 方法进行操作。
掌握这一模式后,您即可在任意 Frame、Labelframe 甚至 Toplevel 窗口中灵活嵌入多标签界面,显著提升 GUI 的组织性与用户体验。










