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

Tkinter中winfo_height()始终返回1的问题求助

解决CTkFrame调用winfo_height()始终返回1的问题

问题场景

点击expand_keyword按钮触发函数,生成多个single_cve_frame(CTkFrame组件)并通过pack()布局到父容器中,需要获取这些框架的实际高度,但调用winfo_height()始终返回1。试过在pack()后调用update_idletasks(),甚至静态设置框架高度,结果还是一样。

用户代码示例:

def expand_keyword(self, frame: ExpandableKeywordCVEsFrame, organized_cves):
        for cve in organized_cves[keyword]['matching_cves']:
            single_cve_frame = ctk.CTkFrame(frame, fg_color = '#E1E1E1')
            ctk.CTkLabel(single_cve_frame,
                         text = cve,
                         text_color = 'black',
                         font = ('Inter', 18)
                         ).place(relx = 0.2, rely = 0.5, relwidth = 0.25, relheight = 1, anchor = 'center')
            
            single_cve_frame.pack(expand = True, fill = 'both')
            print(single_cve_frame.winfo_height())
            self.master.update_idletasks()
            print(single_cve_frame.winfo_height())

原因分析

  1. place()布局不触发父容器尺寸计算:内部的CTkLabel用place()定位,这种布局方式不会向父框架(single_cve_frame)请求空间,导致父框架的自然最小尺寸为1x1。
  2. CTkFrame的尺寸依赖布局状态:CustomTkinter的组件尺寸需要等布局完全渲染后才会确定,即使调用update_idletasks(),如果没有子组件撑大框架,还是会保持最小尺寸。

解决办法

方法1:改用pack()/grid()布局子组件

把内部的CTkLabel换成pack()布局,让父框架自动根据子组件尺寸调整自身大小,之后就能获取正确高度:

def expand_keyword(self, frame: ExpandableKeywordCVEsFrame, organized_cves):
    for cve in organized_cves[keyword]['matching_cves']:
        single_cve_frame = ctk.CTkFrame(frame, fg_color='#E1E1E1')
        # 用pack()替代place()布局Label
        ctk.CTkLabel(single_cve_frame,
                     text=cve,
                     text_color='black',
                     font=('Inter', 18)
                     ).pack(expand=True, fill='both', padx=10, pady=5)
        
        single_cve_frame.pack(expand=True, fill='both', pady=2)
        # 调用update()强制刷新布局
        self.master.update()
        print(single_cve_frame.winfo_height())

方法2:手动设置框架高度并强制刷新

如果必须用place()布局,直接给CTkFrame设置固定高度,再调用update()触发尺寸生效:

def expand_keyword(self, frame: ExpandableKeywordCVEsFrame, organized_cves):
    for cve in organized_cves[keyword]['matching_cves']:
        # 手动指定框架高度
        single_cve_frame = ctk.CTkFrame(frame, fg_color='#E1E1E1', height=40)
        ctk.CTkLabel(single_cve_frame,
                     text=cve,
                     text_color='black',
                     font=('Inter', 18)
                     ).place(relx=0.2, rely=0.5, relwidth=0.25, relheight=1, anchor='center')
        
        single_cve_frame.pack(expand=True, fill='both')
        # 强制更新所有组件布局
        self.master.update()
        print(single_cve_frame.winfo_height())

方法3:绑定<Configure>事件获取真实尺寸

组件最终尺寸可能在布局完成后才确定,给CTkFrame绑定配置事件,当尺寸变化时自动获取:

def on_frame_configure(self, event):
    # event.widget就是当前的single_cve_frame
    print(f"框架实际高度:{event.widget.winfo_height()}")

def expand_keyword(self, frame: ExpandableKeywordCVEsFrame, organized_cves):
    for cve in organized_cves[keyword]['matching_cves']:
        single_cve_frame = ctk.CTkFrame(frame, fg_color='#E1E1E1')
        ctk.CTkLabel(single_cve_frame,
                     text=cve,
                     text_color='black',
                     font=('Inter', 18)
                     ).place(relx=0.2, rely=0.5, relwidth=0.25, relheight=1, anchor='center')
        
        # 绑定尺寸变化事件
        single_cve_frame.bind("<Configure>", self.on_frame_configure)
        single_cve_frame.pack(expand=True, fill='both')

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 14:01:06