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

如何在Flet组件类间实现数据的实时传递?

Flet组件状态同步问题解决:YouTube下载器ID验证与下载模块数据同步

问题场景

使用Python和Flet开发简易YouTube视频下载应用,将界面拆分为两个组件:

  • ID_Section:负责接收并验证YouTube视频/播放列表/短视频的ID,维护valid_id(验证状态)和txt_video_id(输入值)两个状态
  • Download_Section:负责触发下载操作,需要实时获取ID_Section的最新验证状态和输入值

当前问题:Download_Section只能获取ID_Section的初始值,当ID_Section中的valid_id或输入值更新后,Download_Section无法同步获取最新数据。

问题原因

  1. 实例不共享:在Download_Section的__init__方法中,新建了ID_Section()实例来读取状态,这和页面上实际使用的ID_Section是两个完全独立的对象,自然无法获取实时更新的状态。
  2. 无状态监听机制:ID_Section状态变化时,没有通知Download_Section进行更新,也没有让Download_Section直接引用页面上的同一个ID_Section实例。

解决方案

修改思路

  • 在main函数中创建唯一的ID_Section和Download_Section实例,将ID_Section实例传递给Download_Section,让两者共享同一个状态源
  • 让Download_Section直接引用ID_Section的属性,在需要时读取最新值
  • 添加状态监听,让Download_Section根据ID_Section的验证状态自动启用/禁用下载按钮

修改后的完整代码

from yt_dlp import YoutubeDL
import flet as ft
import func


class ID_Section(ft.Column):
    def __init__(self, on_status_change=None):
        super().__init__()
        self.horizontal_alignment = ft.CrossAxisAlignment.CENTER
        self.on_status_change = on_status_change  # 状态变化回调

        self.valid_id = False

        self.txt_video_id = ft.TextField(
            label='Cole o ID do vídeo/short/playlist aqui...', on_change=self.make_invalid
        )
        self.bt_validate_id = ft.ElevatedButton(text="Validar", on_click=self.validate)
        self.txt_id_status = ft.Text('Insira uma ID para começar!', size=14, color='yellow')

        self.controls = [
            ft.Row([
                self.txt_video_id,
                self.bt_validate_id,
            ],
            ft.MainAxisAlignment.CENTER
            ),
            self.txt_id_status,
        ]

    def check_id(self, e):
        if self.valid_id:
             self.txt_id_status.value='ID válida!'
             self.txt_id_status.color='green'
        elif self.txt_video_id.value== '':
             self.txt_id_status.value='Insira uma ID para começar!'
             self.txt_id_status.color='yellow'
        else:
             self.txt_id_status.value='Insira uma ID válida!'
             self.txt_id_status.color='red'
        
        # 状态变化时通知回调
        if self.on_status_change:
            self.on_status_change(self.valid_id, self.txt_video_id.value)
        self.update()

    def make_invalid(self, e):
        self.valid_id = False
        self.check_id(e)

    def validate(self, e):
        if self.txt_video_id.value != '':
            self.valid_id = func.link_validation(self.txt_video_id.value)
            self.check_id(e)

class Download_Section(ft.Column):
    def __init__(self, id_section):
        super().__init__()
        self.horizontal_alignment = ft.CrossAxisAlignment.CENTER
        self.id_section = id_section  # 引用同一个ID_Section实例

        self.btn_download = ft.CupertinoFilledButton(
            content=ft.Text("Baixar"),
            disabled_color='yellow',
            disabled=True,  # 默认禁用
            on_click=self.download_vid
        )

        self.controls = [
            ft.Row(),
            self.btn_download,
        ]

    def update_button_state(self, valid_id, vid_id):
        # 根据验证状态启用/禁用下载按钮
        self.btn_download.disabled = not valid_id or not vid_id.strip()
        self.update()

    def download_vid(self, e):
        # 直接读取ID_Section的最新值
        current_valid = self.id_section.valid_id
        current_vid_id = self.id_section.txt_video_id.value
        print(current_valid)
        print(current_vid_id)
        # 这里添加下载逻辑
        # if current_valid and current_vid_id:
        #     with YoutubeDL() as ydl:
        #         ydl.download([current_vid_id])

def main(page: ft.Page):
    page.title = 'YouTube Downloader'
    page.vertical_alignment = ft.MainAxisAlignment.CENTER
    page.horizontal_alignment = ft.CrossAxisAlignment.CENTER

    # 创建唯一的组件实例
    id_section = ID_Section()
    download_section = Download_Section(id_section)
    
    # 给ID_Section绑定状态变化回调,更新下载按钮状态
    id_section.on_status_change = download_section.update_button_state

    page.add(
        ft.Text('YouTube Downloader', size=28),
        ft.Row(height=20),
        id_section,
        download_section
    )

ft.app(main)

关键修改点

  1. ID_Section添加回调:新增on_status_change参数,在状态变化时触发回调,通知Download_Section更新
  2. Download_Section接收实例引用:在__init__中接收ID_Section实例,直接引用其属性获取最新值
  3. 按钮状态自动更新:通过回调函数update_button_state,根据ID_Section的验证状态自动启用/禁用下载按钮
  4. main函数管理实例:创建唯一的组件实例,确保两者共享同一个状态源

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 08:08:09