Я тоже сталкивался с этой проблемой. Оказалось, что стандартный компонент ft.Tabs в принципе не поддерживает вертикальное отображение, он работает только горизонтально. Поэтому простые решения и не работают.
1) Суть в том, чтобы создать ряд (Row) с двумя колонками:
import flet as ft
import time
def main(page: ft.Page):
page.title = "Вертикальные вкладки - Пример 1"
page.vertical_alignment = ft.MainAxisAlignment.START
tab_content = [
ft.Container(content=ft.Text("Это содержимое первой вкладки"), alignment=ft.alignment.center),
ft.Container(content=ft.Text("Содержимое второй вкладки"), alignment=ft.alignment.center),
ft.Container(content=ft.Column([ft.Text("Третья вкладка"), ft.TextField(label="Введите что-нибудь")]), alignment=ft.alignment.center),
]
content_area = ft.AnimatedSwitcher(
content=tab_content[0],
transition=ft.AnimatedSwitcherTransition.FADE,
duration=300,
reverse_duration=100,
switch_in_curve=ft.AnimationCurve.EASE_IN,
switch_out_curve=ft.AnimationCurve.EASE_OUT,
)
def change_tab(e):
selected_index = e.control.data
content_area.content = tab_content[selected_index]
for i, tab in enumerate(tabs_menu.controls):
if i == selected_index:
tab.bgcolor = ft.colors.BLUE_GREY_700
else:
tab.bgcolor = ft.colors.BLUE_GREY_900
page.update()
tabs = ["Вкладка 1", "Вкладка 2", "Вкладка 3"]
tabs_menu = ft.Column(
spacing=5,
controls=[
ft.Container(
content=ft.Text(name),
padding=10,
border_radius=5,
width=150,
bgcolor=ft.colors.BLUE_GREY_900,
on_click=change_tab,
data=i
) for i, name in enumerate(tabs)
]
)
tabs_menu.controls[0].bgcolor = ft.colors.BLUE_GREY_700
page.add(
ft.Row(
controls=[
ft.Container(
content=tabs_menu,
padding=10,
bgcolor=ft.colors.BLUE_GREY_800,
border_radius=5,
),
ft.Container(
content=content_area,
expand=True,
padding=10,
border_radius=5,
bgcolor=ft.colors.with_opacity(0.05, ft.colors.WHITE),
)
],
vertical_alignment=ft.CrossAxisAlignment.START,
expand=True
)
)
ft.app(target=main)
2) Это специальный компонент Flet как раз для таких боковых меню. Код получается гораздо чище и проще:
import flet as ft
def main(page: ft.Page):
page.title = "Вертикальные вкладки - NavigationRail"
tab_content = [
ft.Container(content=ft.Text("Главная страница"), alignment=ft.alignment.center, expand=True),
ft.Container(content=ft.Text("Страница с настройками"), alignment=ft.alignment.center, expand=True),
ft.Container(content=ft.Text("Страница профиля"), alignment=ft.alignment.center, expand=True),
]
content_view = ft.Column([tab_content[0]], expand=True)
def change_tab(e):
selected_index = e.control.selected_index
content_view.controls[0] = tab_content[selected_index]
page.update()
rail = ft.NavigationRail(
selected_index=0,
label_type=ft.NavigationRailLabelType.ALL,
min_width=100,
min_extended_width=200,
group_alignment=-0.9,
destinations=[
ft.NavigationRailDestination(
icon=ft.icons.HOME_OUTLINED,
selected_icon=ft.icons.HOME,
label="Главная",
),
ft.NavigationRailDestination(
icon_content=ft.Icon(ft.icons.SETTINGS_OUTLINED),
selected_icon_content=ft.Icon(ft.icons.SETTINGS),
label="Настройки",
),
ft.NavigationRailDestination(
icon=ft.icons.PERSON_OUTLINE,
selected_icon=ft.icons.PERSON,
label="Профиль",
),
],
on_change=change_tab,
)
page.add(
ft.Row(
[
rail,
ft.VerticalDivider(width=1),
content_view,
],
expand=True,
)
)
ft.app(target=main)