You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在tkinter组件动态增减时自动调整窗口大小并固定底部按钮

要实现动态调整窗口高度+关闭按钮固定底部的需求,核心是替换当前使用的place绝对定位布局,改用流式布局让Tkinter可以自动计算所有可见组件的总尺寸,修改后的可运行代码如下:

import tkinter as tk

class Application(tk.Tk):
    def __init__(self):
        super().__init__()
        self.title('test')
        # 固定窗口宽度为500,高度后续动态调整
        self.window_width = 500

        # 上层内容容器,存放所有可选组件
        self.content_frame = tk.Frame(self)
        self.content_frame.pack(fill=tk.X, padx=40, pady=20)

        # 初始固定组件
        row1 = tk.Frame(self.content_frame)
        row1.pack(fill=tk.X, pady=5)
        tk.Label(row1, text='Prescribed dose :').pack(side=tk.LEFT)
        self.e1 = tk.Entry(row1, width=10, fg="blue", bd=3)
        self.e1.pack(side=tk.RIGHT)

        row2 = tk.Frame(self.content_frame)
        row2.pack(fill=tk.X, pady=5)
        tk.Label(row2, text='Is there another target ?').pack(side=tk.LEFT)
        self.radioValueOuiNonPourBoostPresent = tk.IntVar()
        tk.Radiobutton(row2, text='Yes', variable=self.radioValueOuiNonPourBoostPresent, value=1, command=self.create_firstWidget).pack(side=tk.LEFT, padx=20)
        tk.Radiobutton(row2, text='No', variable=self.radioValueOuiNonPourBoostPresent, value=2, command=self.hide_selection).pack(side=tk.LEFT)

        # 第一层级可选组件容器
        self.first_level_frame = tk.Frame(self.content_frame)
        # 第二层级可选组件容器
        self.second_level_frame = tk.Frame(self.content_frame)

        # 底部固定关闭按钮
        self.c2 = tk.Button(self, text='Quit', fg='White', bg='dark green', height=1, width=10, command=self.destroy)
        self.c2.pack(side=tk.BOTTOM, pady=15)

        # 初始窗口自适应大小
        self.update_window_height()

    def create_firstWidget(self):
        if self.radioValueOuiNonPourBoostPresent.get() == 1:
            # 清空容器避免重复创建组件
            for widget in self.first_level_frame.winfo_children():
                widget.destroy()
            # 填充第一层级组件
            row1 = tk.Frame(self.first_level_frame)
            row1.pack(fill=tk.X, pady=5)
            tk.Label(row1, text='Prescribed dose of the 2nd target :').pack(side=tk.LEFT)
            self.doseBoost = tk.StringVar(self)
            tk.Entry(row1, textvariable=self.doseBoost, width=10, fg="blue", bd=3).pack(side=tk.RIGHT)

            row2 = tk.Frame(self.first_level_frame)
            row2.pack(fill=tk.X, pady=5)
            tk.Label(row2, text='Is it a sequential scheme ?').pack(side=tk.LEFT)
            self.rdioOuiNonSequentiel = tk.IntVar()
            tk.Radiobutton(row2, text='Yes', variable=self.rdioOuiNonSequentiel, value=1, command=self.create_secondtWidget).pack(side=tk.LEFT, padx=20)
            tk.Radiobutton(row2, text='No', variable=self.rdioOuiNonSequentiel, value=2, command=self.hide_selection2).pack(side=tk.LEFT)

            self.first_level_frame.pack(fill=tk.X, pady=5)
            self.update_window_height()

    def create_secondtWidget(self):
        if self.rdioOuiNonSequentiel.get() == 1:
            for widget in self.second_level_frame.winfo_children():
                widget.destroy()
            row = tk.Frame(self.second_level_frame)
            row.pack(fill=tk.X, pady=5)
            tk.Label(row, text='Number of fractions').pack(side=tk.LEFT)
            self.nombreFractionsBoost = tk.StringVar(self)
            tk.Entry(row, textvariable=self.nombreFractionsBoost, width=10, fg="blue", bd=3).pack(side=tk.RIGHT)

            self.second_level_frame.pack(fill=tk.X, pady=5)
            self.update_window_height()

    def hide_selection(self):
        if self.radioValueOuiNonPourBoostPresent.get() == 2:
            self.first_level_frame.pack_forget()
            self.second_level_frame.pack_forget()
            self.update_window_height()

    def hide_selection2(self):
        if self.rdioOuiNonSequentiel.get() == 2:
            self.second_level_frame.pack_forget()
            self.update_window_height()

    def update_window_height(self):
        # 刷新组件布局,获取最新的所需高度
        self.update()
        # 计算当前所有组件总高度,设置窗口尺寸,宽度固定为500
        current_height = self.winfo_reqheight()
        self.geometry(f"{self.window_width}x{current_height}")


if __name__ == "__main__":
    app = Application()
    app.mainloop()

本次修改的核心逻辑:

  • 用Frame分组管理不同层级的可选组件,显示隐藏直接操作整个Frame即可,不需要逐个处理单个组件
  • 关闭按钮单独放在窗口底部,不受上层组件增减的影响,始终固定在最下方
  • 每次组件显示/隐藏后,自动计算当前所有可见组件的总高度,调整窗口尺寸,宽度固定为你预设的500px
  • 优化了组件判断逻辑,不会出现组件未创建时调用方法报错的问题

内容的提问来源于stack exchange,提问作者Romain

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 13:24:05