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

如何在Flet框架中将函数值传递至ft.Text?秒表开发遇阻

Flet秒表实现:解决循环内时间值传递问题

你的核心问题在于:直接在主线程里跑while循环会阻塞Flet的UI线程,导致界面无响应;而且更新Text组件后没触发UI刷新,同时return会直接终止循环,自然拿不到持续更新的时间值。下面给你两种可行的实现方案:

方案一:用线程避免UI阻塞

通过线程单独运行秒表循环,不占用UI主线程,同时手动触发UI刷新:

import flet as ft
import threading
import time

def main(page: ft.Page):
    page.title = "Flet秒表"
    time_display = ft.Text(value="00:00:00", size=30)
    is_running = False
    total_seconds = 0

    def format_time(seconds):
        hours = seconds // 3600
        minutes = (seconds % 3600) // 60
        secs = seconds % 60
        return f"{hours:02d}:{minutes:02d}:{secs:02d}"

    def stopwatch():
        nonlocal total_seconds, is_running
        while is_running:
            total_seconds += 1
            time_display.value = format_time(total_seconds)
            # 必须调用update()通知Flet刷新UI
            time_display.update()
            time.sleep(1)

    def start_clicked(e):
        nonlocal is_running
        if not is_running:
            is_running = True
            # 启动后台线程运行秒表,不阻塞UI
            threading.Thread(target=stopwatch, daemon=True).start()

    def stop_clicked(e):
        nonlocal is_running
        is_running = False

    def reset_clicked(e):
        nonlocal is_running, total_seconds
        is_running = False
        total_seconds = 0
        time_display.value = "00:00:00"
        time_display.update()

    page.add(
        time_display,
        ft.Row(
            [
                ft.ElevatedButton("开始", on_click=start_clicked),
                ft.ElevatedButton("停止", on_click=stop_clicked),
                ft.ElevatedButton("重置", on_click=reset_clicked)
            ]
        )
    )

if __name__ == "__main__":
    ft.app(target=main)

方案二:用Flet内置Timer组件(更贴合框架特性)

不用手动管理线程,直接用Flet的Timer组件定时更新时间,更简洁:

import flet as ft

def main(page: ft.Page):
    page.title = "Flet秒表"
    time_display = ft.Text(value="00:00:00", size=30)
    total_seconds = 0
    timer = None

    def format_time(seconds):
        hours = seconds // 3600
        minutes = (seconds % 3600) // 60
        secs = seconds % 60
        return f"{hours:02d}:{minutes:02d}:{secs:02d}"

    def update_timer():
        nonlocal total_seconds
        total_seconds += 1
        time_display.value = format_time(total_seconds)
        time_display.update()

    def start_clicked(e):
        nonlocal timer
        if not timer:
            # 创建每秒触发一次的重复定时器
            timer = ft.Timer(1, update_timer, repeat=True)
            page.add(timer)
            timer.start()

    def stop_clicked(e):
        nonlocal timer
        if timer:
            timer.cancel()
            timer = None

    def reset_clicked(e):
        nonlocal total_seconds, timer
        if timer:
            timer.cancel()
            timer = None
        total_seconds = 0
        time_display.value = "00:00:00"
        time_display.update()

    page.add(
        time_display,
        ft.Row(
            [
                ft.ElevatedButton("开始", on_click=start_clicked),
                ft.ElevatedButton("停止", on_click=stop_clicked),
                ft.ElevatedButton("重置", on_click=reset_clicked)
            ]
        )
    )

if __name__ == "__main__":
    ft.app(target=main)

关键注意点

  1. 绝对不能在UI主线程里跑无阻塞的while循环,会导致界面彻底卡死。
  2. 更新Text组件的值后,必须调用update()方法,Flet才会刷新该组件的显示。
  3. 用状态标志(如is_running)或定时器的启停来控制秒表运行,不要用return终止循环。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 10:44:50