如何在Python中使用flet框架实现NavigationBar?

问题描述 投票:0回答:1

我目前正在开发一个使用“flet”框架的项目,这是一个基于 Flutter 的 Python GUI 框架。我正在尝试实现一个具有不同视图的导航栏,类似于选项卡栏,但我遇到了一些困难。我创建了一个名为

NavBar
的类,它继承自
ft.NavigationBar
,并且定义了导航目的地和相应的视图。但是,我不确定我是否以正确的方式这样做,或者是否有更好的选择。

这是我的代码的简化版本:

from typing import Any, List
import flet as ft
from flet_core.control import OptionalNumber
from flet_core.navigation_bar import (
    NavigationBarLabelBehavior,
    NavigationDestination,
)
from flet_core.ref import Ref
from flet_core.types import (
    AnimationValue,
    OffsetValue,
    ResponsiveNumber,
    RotateValue,
    ScaleValue,
)
from inextracker.ui.widgets.colors import dark_theme, light_theme


class NavBar(ft.NavigationBar):
    def __init__(
        self,
        navigation_destinations: List[ft.NavigationDestination],
        navigation_views: List[ft.Control],
        pg: ft.Page,
        ref: Ref | None = None,
        width: OptionalNumber = None,
        height: OptionalNumber = None,
        left: OptionalNumber = None,
        top: OptionalNumber = None,
        right: OptionalNumber = None,
        bottom: OptionalNumber = None,
        expand: bool | int | None = None,
        col: ResponsiveNumber | None = None,
        opacity: OptionalNumber = None,
        rotate: RotateValue = None,
        scale: ScaleValue = None,
        offset: OffsetValue = None,
        aspect_ratio: OptionalNumber = None,
        animate_opacity: AnimationValue = None,
        animate_size: AnimationValue = None,
        animate_position: AnimationValue = None,
        animate_rotation: AnimationValue = None,
        animate_scale: AnimationValue = None,
        animate_offset: AnimationValue = None,
        on_animation_end=None,
        visible: bool | None = None,
        disabled: bool | None = None,
        data: Any = None,
        destinations: List[NavigationDestination] | None = None,
        selected_index: int | None = None,
        bgcolor: str | None = None,
        label_behavior: NavigationBarLabelBehavior | None = None,
        elevation: OptionalNumber = None,
        on_change=None,
    ):
        super().__init__(
            ref,
            width,
            height,
            left,
            top,
            right,
            bottom,
            expand,
            col,
            opacity,
            rotate,
            scale,
            offset,
            aspect_ratio,
            animate_opacity,
            animate_size,
            animate_position,
            animate_rotation,
            animate_scale,
            animate_offset,
            on_animation_end,
            visible,
            disabled,
            data,
            destinations,
            selected_index,
            bgcolor,
            label_behavior,
            elevation,
            on_change,
        )
        self.navigation_destinations = navigation_destinations
        self.navigation_views = navigation_views
        self.pg = pg
        self.pre_check()

        self.destinations = self.navigation_destinations

        self.destination_index_to_views_mapping = (
            self.create_destination_view_mapping()
        )

        self.selected_index = 0
        self.elevation = 6.6666666666
        self.destinations = self.navigation_destinations
        self.on_change = self.on_changing_navigation_page

    def on_changing_navigation_page(self, e):
        for index, control in self.destination_index_to_views_mapping:
            if index == self.selected_index:
                print(
                    f"onChange: {index=} == {self.selected_index=}\nVisible -> True\n\t============="
                )
                control.visible = True

            else:
                print(
                    f"onChange: {index=} != {self.selected_index=}\nVisible -> False\n\t============="
                )
                control.visible = False
        else:
            print("onChange: Updates")
            self.update()
            self.pg.update()

    def create_destination_view_mapping(self):
        if len(self.navigation_destinations) == len(self.navigation_views):
            print("create_destination_view_mapping: Returning Mapping")
            return tuple(enumerate(self.navigation_views))
        else:
            raise Exception("Unequal Mappings Supplied")

    def pre_check(self):
        for view in self.navigation_views:
            view.visible = False
            print(f"Precheck: Setting Visible -> False")

        else:
            self.navigation_views[0].visible = True
            print("Precheck: Update")
            self.pg.update()


def main(page: ft.Page):
    def theme_changed(e):
        page.theme_mode = (
            ft.ThemeMode.DARK
            if page.theme_mode == ft.ThemeMode.LIGHT
            else ft.ThemeMode.LIGHT
        )
        theme_switcher.label = (
            "Light theme"
            if page.theme_mode == ft.ThemeMode.LIGHT
            else "Dark theme"
        )

        page.theme = (
            light_theme
            if page.theme_mode == ft.ThemeMode.LIGHT
            else dark_theme
        )

        page.update()

    page.theme_mode = ft.ThemeMode.LIGHT
    theme_switcher = ft.Switch(label="Light theme", on_change=theme_changed)
    page.add(theme_switcher)

    d1 = ft.NavigationDestination(icon=ft.icons.BOOKMARK)
    d2 = ft.NavigationDestination(icon=ft.icons.BOOKMARK)
    d3 = ft.NavigationDestination(icon=ft.icons.BOOKMARK)

    v1 = ft.Text("v1")
    v2 = ft.Text("v2")
    v3 = ft.Text("v3")

    page.add(v1)
    page.add(v2)
    page.add(v3)

    page.navigation_bar = NavBar(
        navigation_destinations=[d1, d2, d3],
        navigation_views=[v1, v2, v3],
        pg=page,
    )
    page.update()


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

我特别关心 on_chang_navigation_page 方法以及我是否正确管理视图可见性。任何有关我的方法的反馈或关于在“flet”框架内实现此导航栏功能的更好方法的建议将不胜感激。

python flutter user-interface navigationbar flet
1个回答
0
投票

个人考虑,最重要的是定义一个类功能,将其应用程序栏与内容内容一起使用,以实现内容的功能,并使用 page.go("/") 实现功能。

Para el enrutamiento puedes ver este 帖子:

© www.soinside.com 2019 - 2024. All rights reserved.