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

CustomTkinter更新帧中文字闪烁故障的排查与解决问询

问题

在CustomTkinter程序中,我用一个标准Tkinter帧来显示地铁线路状态信息,每次通过OptionMenu选择不同线路后,帧会更新内容。但操作1-2次以上后,部分文字出现闪烁故障。我猜测可以通过每次操作时更新帧来解决,但编程基础薄弱,不知道具体怎么实现。相关代码如下:

def linepick(linechoice):
    
    if linechoice == "Waterloo & City":
        linechoice = "waterloo-city"

    else:
        None
       
    if linechoice == "Hammersmith & City":
        linechoice = "hammersmith-city"

    else:
        None

    endpoint = f"https://api.tfl.gov.uk/Line/{linechoice}/Status"
    response = requests.get(endpoint)
    
    if response.status_code == 200:
       
       data = response.json()

       if len(data) > 0 and "lineStatuses" in data[0]:
           linedata1 = data[0]["lineStatuses"][0]
           
           if linechoice == "waterloo-city":
            linechoice = "Waterloo & City"

           else:
            None
       
           if linechoice == "hammersmith-city":
            linechoice = "Hammersmith & City"

           else:
            None

           label1 = ct.CTkLabel(frame, text=f'{linechoice} line:{linedata1["statusSeverityDescription"]}', font=("Arial", 16))
           label1.place(x=0, y=30)
    
    elif response.status_code == 300:

        redirection = response.headers["location"]
        rerequest = requests.get(redirection)
        rerequestdata = rerequest.json()

        if len(rerequestdata) > 0 and "lineStatuses" in rerequestdata[0]:
            # 原代码此处存在拼写错误:lineStauses -> lineStatuses
            linedata2 = rerequestdata[0]["lineStauses"][0]

            if linechoice == "waterloo-city":
             linechoice = "Waterloo & City"

            else:
             None
       
            if linechoice == "hammersmith-city":
              linechoice = "Hammersmith & City"

            else:
             None

            label2 = ct.CTkLabel(frame, text=f'{linechoice} line:{linedata2["statusSeverityDescription"]}', font=("Arial", 16))
            label2.place(x=0, y=30)

    else:
       label3 = ct.CTkLabel(frame, text="Status line not reached, try again later.", font=("Arial", 16))
       label3.place(x=0, y=30)
    

# 创建OptionMenu
stationmenu = ct.CTkOptionMenu(
    issuewindow, 
    values=["Bakerloo","Waterloo & City","Central","Circle","District","Hammersmith & City","Jubilee","Metropolitan","Northern","Piccadilly","Victoria"], 
    font=("Arial", 20), 
    corner_radius=10,
    fg_color="#0C56FF",
    command=linepick)
stationmenu.place(x=35, y=40)

解决方案

故障原因

每次选择新线路时,你都在同一位置创建新的CTkLabel控件,旧的Label并没有被销毁。多个Label重叠在一起,界面渲染时会出现短暂的叠加冲突,这就是文字闪烁的根本原因。

解决方法

  1. 提前创建固定Label:在初始化阶段就创建好用于显示状态的Label,而不是每次请求后新建
  2. 仅更新Label内容:每次获取到新数据后,只修改已有Label的text属性
  3. 优化线路名称转换:用字典映射替代重复的if判断,简化代码逻辑

修改后的代码

# 先在全局或类初始化阶段创建好固定的状态Label(需确保frame已提前创建)
status_label = ct.CTkLabel(frame, text="请选择一条线路查看状态", font=("Arial", 16))
status_label.place(x=0, y=30)

# 线路名称映射字典,避免重复的if判断,后续新增特殊线路只需在此添加
LINE_NAME_MAP = {
    "Waterloo & City": "waterloo-city",
    "Hammersmith & City": "hammersmith-city"
}

def linepick(linechoice):
    # 转换线路名称为API要求的格式
    api_line_name = LINE_NAME_MAP.get(linechoice, linechoice)
    
    endpoint = f"https://api.tfl.gov.uk/Line/{api_line_name}/Status"
    response = requests.get(endpoint)
    
    # 统一处理重定向逻辑,避免重复代码
    if response.status_code == 300:
        redirection = response.headers["location"]
        response = requests.get(redirection)
    
    if response.status_code == 200:
        data = response.json()
        if len(data) > 0 and "lineStatuses" in data[0]:
            linedata = data[0]["lineStatuses"][0]
            # 把API用的名称转回显示用的名称
            display_name = next((k for k, v in LINE_NAME_MAP.items() if v == api_line_name), api_line_name)
            # 仅更新已有Label的文本内容
            status_label.configure(text=f'{display_name} line: {linedata["statusSeverityDescription"]}')
    else:
        status_label.configure(text="无法获取线路状态,请稍后重试。")
    

# 创建OptionMenu
stationmenu = ct.CTkOptionMenu(
    issuewindow, 
    values=["Bakerloo","Waterloo & City","Central","Circle","District","Hammersmith & City","Jubilee","Metropolitan","Northern","Piccadilly","Victoria"], 
    font=("Arial", 20), 
    corner_radius=10,
    fg_color="#0C56FF",
    command=linepick)
stationmenu.place(x=35, y=40)

额外说明

  • 修正了原代码中的拼写错误:lineStauses改为lineStatuses
  • 用字典映射线路名称,代码更简洁易维护
  • 统一处理重定向逻辑,减少冗余代码
  • 仅更新已有Label的内容,不会创建新控件,彻底解决闪烁问题

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 08:12:44