Flet异步更新图标异常求助:文本正常更新但图标无变化
问题分析与解决方案
核心问题
- 图标引用未动态绑定:你把
countdown.icon传给CupertinoListTile.leading后,后续修改self.icon只是替换了Countdown实例的属性,而ListTile引用的还是最初创建的那个Icon对象,界面自然不会更新。 - 同步请求阻塞事件循环:
requests.get是同步IO操作,会卡住Flet的异步任务队列,导致UI更新延迟甚至无响应。 - 异常分支代码错误:
except块里把self.icon设成ft.icons.WIFI(图标常量)而非Icon实例,会导致后续逻辑出错。
修复后的代码
import asyncio import flet as ft import aiohttp # 改用异步请求库 class Countdown(ft.UserControl): def __init__(self): super().__init__() self.running = False self.status_text = ft.Text("Connecting...") # 初始化可复用的Icon实例,后续仅修改name属性 self.status_icon = ft.Icon(ft.icons.SIGNAL_WIFI_STATUSBAR_NULL_OUTLINED) def build(self): return ft.Row([self.status_icon, self.status_text]) def did_mount(self): self.running = True self.page.run_task(self.update_timer) def will_unmount(self): self.running = False async def update_timer(self): while self.running: try: # 异步请求替代同步requests,避免阻塞事件循环 async with aiohttp.ClientSession() as session: async with session.get("http://www.google.com", timeout=3): self.status_text.value = "Connected" self.status_icon.name = ft.icons.WIFI # 修改现有Icon的name属性 except (aiohttp.ClientError, asyncio.TimeoutError): self.status_text.value = "Disconnected" self.status_icon.name = ft.icons.SIGNAL_WIFI_STATUSBAR_NULL_OUTLINED # 触发组件更新 self.update() await asyncio.sleep(5) def create_statusbar(): countdown = Countdown() return ft.Container( content=ft.Row( [ ft.CupertinoListTile( bgcolor_activated=ft.colors.AMBER_ACCENT, leading=countdown.status_icon, # 直接绑定Icon实例 title=countdown.status_text, width=180, ), ft.CupertinoListTile( bgcolor_activated=ft.colors.AMBER_ACCENT, leading=ft.Icon(name=ft.icons.API), title=ft.Text("API Status"), subtitle=ft.Text("Checking..."), width=150, ), ft.CupertinoListTile( bgcolor_activated=ft.colors.AMBER_ACCENT, leading=ft.Icon(name=ft.icons.API), title=ft.Text("API Status"), subtitle=ft.Text("Checking..."), width=150, ), ft.CupertinoListTile( bgcolor_activated=ft.colors.AMBER_ACCENT, leading=ft.Icon(name=ft.icons.API), title=ft.Text("API Status"), subtitle=ft.Text("Checking..."), width=150, ), ], ), border=ft.border.all(1, ft.colors.GREY_700), border_radius=ft.border_radius.all(10), )
关键修改说明
- 让
Countdown继承ft.UserControl,组合Icon和Text组件,统一管理UI元素。 - 不再替换整个Icon实例,而是修改现有Icon对象的
name属性,确保UI引用的是同一个对象,修改后能同步刷新。 - 用
aiohttp异步请求替代同步requests,避免阻塞Flet的事件循环,保证UI响应流畅。 - 修正异常分支的图标设置逻辑,恢复为断开状态的正确图标。
内容的提问来源于stack exchange,提问作者Sinterf
相关产品推荐
相关产品推荐

