0

I am new to Flet, I was use to tkinter and creating new windows for each activity. Now on flet I am trying to re-make the same application in a modern way. The problem I have is when navigating screens (previously done with buttons on tkinter) I am using a NavigationRail control, but It only shows on my "home" screen, the first screen to be render on the page. But when I change the view making use of the Navigation Rail it does not appear on that new screen.

My guess is I shouldn't include the navigationrail on each view, but to have 2 rows, one for the rail and another one for the corresponding view, but when trying it I just get a white screen as if the view component were using all available screen. This is the simplest code I have worked out that reflects the problem. There's no backend into this code.

import flet as ft

def main(page: ft.Page):
    page.title= "Utilidades Pintura"
    page.window_width = 600
    page.window_height = 500
    page.window_resizable = False

    rail = ft.NavigationRail(
        selected_index=0,
        label_type=ft.NavigationRailLabelType.ALL,
        # extended=True,
        min_width=100,
        min_extended_width=400,
        group_alignment=-0.9,
        height=500,
        width=100,
        destinations=[
            ft.NavigationRailDestination(
                icon=ft.icons.FAVORITE_BORDER, selected_icon=ft.icons.FAVORITE, label="First"
            ),
            ft.NavigationRailDestination(
                icon_content=ft.Icon(ft.icons.BOOKMARK_BORDER),
                selected_icon_content=ft.Icon(ft.icons.BOOKMARK),
                label="Second",
            ),
            ft.NavigationRailDestination(
                icon=ft.icons.SETTINGS_OUTLINED,
                selected_icon_content=ft.Icon(ft.icons.SETTINGS),
                label_content=ft.Text("Settings"),
            ),
        ],
        on_change=lambda e: page.go("/test"),
    )

    #Views for each screen
    home_view = ft.View(
                    route="/",
                    controls=[
                        ft.Row(
                            controls=[
                                rail,
                                ft.Text("Home screen"),
                            ]
                        )
                    ]
                )
    test_view = ft.View(
                    route="/test",
                    controls=[
                        ft.Row(
                            controls=[
                                rail,
                                ft.Text("Test screen!"),
                            ]
                        )
                    ]
                )
   

    def route_change(route):
        page.views.clear()
        page.views.append(home_view)    
        if page.route == "/test":
            page.views.append(test_view)
        page.update()


    def view_pop(view):
        page.views.pop()
        top_view = page.views[-1]
        page.go(top_view.route)

    page.on_route_change = route_change
    page.on_view_pop = view_pop
    page.go(page.route)
    print(page.route)

ft.app(target=main)

The output of this code is Home screen, where rail do shows up Test screen, where rail does not show up

Gbenga B Ayannuga
  • 2,407
  • 3
  • 17
  • 38

2 Answers2

0

I had the same problem. In my program, I wanted to use a menu on the left, i.e. a navigation rail, but on a view change in the new view the navigation rail simply wasn't showing up. I have solved by modifying the code from this:

def route_change(route):
    page.views.clear()
    page.views.append(home_view)    
    if page.route == "/test":
        page.views.append(test_view)
    page.update()

to this:

def route_change(route):
        page.views.clear()
        if page.route == '/:
            page.views.append(home_view)    
        if page.route == "/test":
            page.views.append(test_view)
        page.update()

In addition, I think (but I am not sure since I'm using flet since only 2 days) that if you are not using an appbar, you do not need the function view_pop.

Let me know if it works.

bjorn
  • 338
  • 6
  • 18
0

Here is one more approach. First create a list of Screens. Here is an example.

screen_list = [ft.Text(...), ft.Text(...)]

After that, create a widget in which you want to show these screens. Let's say a container.

container = ft.Container(content=screen_list[0], expand=True)

Notice that the container is defined with the first screen. So, whenever the application starts, it will show the first screen initially.

Now, you have to define a function just like below. you can change the function name according to your needs.

def set_screen(e):
    container.content = screen_list[e.control.selected_index]
    page.update()

Now just call this function in on_change of NavigationRail and add the container in a row with the NavigationRail in page.add(), and you are good to go.

Here is the full code.

import flet as ft


def main(page: ft.Page):
    screen_list = [ft.Text(...), ft.Text(...)]
    container = ft.Container(content=screen_list[0], expand=True)

    def set_screen(e):
        container.content = screen_list[e.control.selected_index]
        page.update()

    nav_rail = ft.NavigationRail(
        selected_index=0,
        label_type=ft.NavigationRailLabelType.ALL,
        min_width=100,
        min_extended_width=200,
        destinations=[
            ft.NavigationRailDestination(
                icon_content=ft.Icon(ft.icons.PERSON_OUTLINE,),
                selected_icon_content=ft.Icon(ft.icons.PERSON,),
                label="About",
            ),
            ft.NavigationRailDestination(
                icon_content=ft.Icon(ft.icons.WORK_OUTLINE,),
                selected_icon_content=ft.Icon(ft.icons.WORK,),
                label="Projects",
            ),
        ],
        on_change=set_screen
    )

    page.add(
        ft.Row(
            [
                nav_rail,
                container,
            ],
            expand=True,
        )
    )


ft.app(target=main)

Modify the widgets according to yours needs. It is a simple example by which you can understand what is going on.

I hope it helps.