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

Flet框架page.drawer报错AssertionError:控件需先添加至页面

解决Flet框架中的AssertionError: Control must be added to the page first错误

错误原因分析

  • 重复复用同一控件实例:header控件被同时添加到PaginaInicio和PaginaCuaderno两个自定义控件中,Flet不允许同一个控件实例绑定到多个父容器,路由切换时会触发断言错误。
  • Drawer更新逻辑错误:show_drawer函数中直接调用page.drawer.update(),Drawer作为Page的内置组件,应该通过page.update()来触发页面整体更新。
  • 控件实例化错误:PaginaInicio中直接使用Welcome类而非其实例Welcome(),导致无效控件被添加。

修复方案

  1. 避免控件实例重复使用:将header的创建逻辑封装为函数,在每个自定义UserControl的build方法内部调用,确保每个页面都使用独立的header实例。
  2. 修正Drawer更新方式:将show_drawer中的page.drawer.update()替换为page.update()。
  3. 正确实例化控件:将Welcome改为Welcome()(假设Welcome是Flet控件类)。
  4. 移除多余的page.add调用:设置page.drawer后无需手动调用page.add(page.drawer),Flet会自动处理Drawer与页面的关联。

修改后的完整代码

import flet as ft
from textos import Welcome

def main(page = ft.Page):
    page.title = 'Mejora tu glucemia'
    page.padding = ft.padding.only(
        top = 0,
        bottom = 0,
        left = 0,
        right = 0
    )
    page.window_height = 900
    page.window_width = 400

    header_height = page.window_height * 0.08
    body_height = page.window_height - header_height

    def navigation_drawer_changed(e):
        selected = e.control.selected_index
        if selected == 0:
            page.go('/')
        elif selected == 1:
            page.go('/cuaderno')

    page.drawer = ft.NavigationDrawer(
        on_change= navigation_drawer_changed,
        controls = [
            ft.Container(height=12),
            ft.NavigationDrawerDestination(
                label = 'Inicio',
                icon = ft.icons.DOOR_BACK_DOOR_OUTLINED,
                selected_icon_content = ft.Icon(ft.icons.DOOR_BACK_DOOR)
            ),
            ft.Container(height=12),
            ft.Container(height=2, bgcolor= ft.colors.BLACK),
            ft.Container(height=12),
            ft.NavigationDrawerDestination(
                label = 'Cuaderno',
                icon = ft.icons.BOOKMARK_BORDER_OUTLINED,
                selected_icon_content = ft.Icon(ft.icons.BOOKMARK)
            ),
            ft.Container(height=12),
            ft.NavigationDrawerDestination(
                label = 'Añadir notas',
                icon = ft.icons.BORDER_COLOR_OUTLINED,
                selected_icon_content = ft.Icon(ft.icons.BORDER_COLOR)
            )
        ]
    )

    def show_drawer(e):
        page.drawer.open = True
        page.update()  # 修正为更新整个页面

    # 将header封装为可复用的创建函数
    def create_header():
        return ft.Container(
            height= header_height,
            padding = ft.padding.only(
                left = page.window_width*0.05,
                right = page.window_width*0.05
            ),
            shadow = ft.BoxShadow(
                blur_radius=1,
                spread_radius=1,
                color=ft.colors.BLACK,
                offset=ft.Offset(0, 1),
            ),
            bgcolor = ft.colors.BLACK,
            content = ft.Column(
                alignment = 'center',
                controls= [
                    ft.Row(
                        alignment= 'spaceBetween',
                        controls = [
                            ft.IconButton(icon = ft.icons.MENU, on_click=show_drawer)
                        ]
                    )
                ]
            )
        )

    class PaginaInicio(ft.UserControl):
        def build(self):
            return ft.Column(
                spacing= 0,
                controls= [
                    create_header(),  # 使用独立的header实例
                    ft.Container(
                        height= body_height,
                        bgcolor= ft.colors.WHITE,
                        content = ft.Row(
                            alignment= 'center',
                            controls = [
                                ft.Column(
                                    alignment= 'center',
                                    controls= [
                                        Welcome()  # 实例化控件
                                    ]
                                )
                            ]
                        )
                    )
                ]
            )

    class PaginaCuaderno(ft.UserControl):
        def build(self):
            return ft.Column(
                spacing= 0,
                controls= [
                    create_header(),  # 使用独立的header实例
                    ft.Container(
                        height= body_height,
                        bgcolor= ft.colors.WHITE,
                        content = ft.Row(
                            alignment= 'center',
                            controls = [
                                ft.Column(
                                    alignment= 'center',
                                    controls= [
                                    ]
                                )
                            ]
                        )
                    )
                ]
            )

    pagina_inicio = PaginaInicio()
    pagina_cuaderno = PaginaCuaderno()

    pages = {
        '/': ft.View(
            "/",
            [
                pagina_inicio
            ]
        ),
        '/cuaderno': ft.View(
            "/cuaderno",
            [
                pagina_cuaderno
            ]
        )
    }

    def route_change(route):
        page.views.clear()
        page.views.append(pages[page.route])
        page.update()

    page.on_route_change = route_change
    page.go(page.route)

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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 14:38:12