-
Notifications
You must be signed in to change notification settings - Fork 11
Description
- Documentation
The use of cache is very useful for applications where changing pages does not change the processes that are being carried out, that is, if you return to the page the controls remain running in the background without stopping when changing pages (route). An example would be the use of a counter when initializing and moving to another page (route) and returning to the counter page, the counter would have increased its value without stopping the process.
Features:
-
When returning to the same page the
View
is not reloaded, the controls remain as they were, with the same processes carried out. -
It is not necessary to use the
page_run_task
method to run processes, but it is recommended.
How to use?
To activate the use of the page cache, you only need to activate it from the cache
parameter, which by default is cache=False
example:
import asyncio
import random
import flet as ft
import flet_easy as fs
app = fs.FletEasy()
# remove animation on route change
@app.config
def config(page: ft.Page):
page.theme = ft.Theme(
page_transitions=ft.PageTransitionsTheme(
windows=ft.PageTransitionTheme.NONE,
android=ft.PageTransitionTheme.NONE,
ios=ft.PageTransitionTheme.NONE,
macos=ft.PageTransitionTheme.NONE,
linux=ft.PageTransitionTheme.NONE,
),
)
# use in 'data.view'
@app.view
def config_view(data: fs.Datasy):
def change_color(e: ft.ControlEvent):
colors = [ft.Colors.RED, ft.Colors.GREEN, ft.Colors.BLUE, ft.Colors.YELLOW]
appbar.bgcolor = random.choice(colors)
data.page.update()
appbar = ft.AppBar(
bgcolor=ft.Colors.BLACK45,
actions=[
ft.IconButton(
icon=ft.Icons.RESTART_ALT_ROUNDED,
icon_color=ft.Colors.WHITE,
on_click=change_color,
)
],
)
def index_bar_route(e: ft.ControlEvent):
route = e.control.selected_index
if route == 0:
data.go("/")()
elif route == 1:
data.go("/test2")()
elif route == 2:
data.go("/test3")()
return ft.View(
appbar=appbar,
navigation_bar=ft.NavigationBar(
destinations=[
ft.NavigationBarDestination(icon=ft.Icons.CODE, label="counter 1"),
ft.NavigationBarDestination(icon=ft.Icons.SYNC_DISABLED, label="counter 2"),
ft.NavigationBarDestination(
icon=ft.Icons.CODE,
label="counter 3",
),
],
on_change=index_bar_route,
),
)
# control custom
class Counter(ft.Container):
def __init__(self, update, color: str):
super().__init__()
self.update = update
self.number = ft.TextField(value="0", text_size=50, text_align="center")
self.content = ft.Column(
controls=[
self.number,
ft.FilledButton("start", on_click=self.start, height=50),
],
horizontal_alignment="center",
)
self.width = 400
self.bgcolor = color
self.border_radius = 10
self.padding = 20
async def start(self, e):
while True:
self.number.value = str(int(self.number.value) + 1)
self.update()
await asyncio.sleep(1)
# add cache to the page
@app.page("/", title="Test 1", cache=True)
def index_page(data: fs.Datasy):
page = data.page
data.view.appbar.title = ft.Text("Test 1")
return ft.View(
controls=[
ft.Text("Counter 1", size=50),
Counter(page.update, ft.Colors.RED),
],
appbar=data.view.appbar,
navigation_bar=data.view.navigation_bar,
horizontal_alignment="center",
vertical_alignment="center",
)
@app.page("/test2", title="Test 2")
def test_page(data: fs.Datasy):
page = data.page
data.view.appbar.title = ft.Text("Test 2")
return ft.View(
controls=[
ft.Text("Counter 2 - (cache disabled)", size=50),
Counter(page.update, ft.Colors.BLUE),
],
appbar=data.view.appbar,
navigation_bar=data.view.navigation_bar,
vertical_alignment="center",
horizontal_alignment="center",
)
# add cache to the page
@app.page("/test3", title="Test 3", cache=True)
async def test2_page(data: fs.Datasy):
page = data.page
data.view.appbar.title = ft.Text("Test 3")
return ft.View(
controls=[
ft.Text("Counter 3", size=50),
Counter(page.update, ft.Colors.GREEN),
],
appbar=data.view.appbar,
navigation_bar=data.view.navigation_bar,
horizontal_alignment="center",
vertical_alignment="center",
)
app.run()
🎬Demo
use-cache-page-1.mp4
data.dynamic_control
This feature is particularly useful when you need to maintain the dynamic state of a control while navigating between different pages. When you enable the cache
option on a page, shared controls will keep their state even if they are modified on other pages.
It works perfectly with controls shared through the view
decorator of the FletEasy
instance, allowing a consistent user experience throughout the application.
data.dynamic_control
: Is a method for dynamic UI control updates.
Parameters:
- control: The UI control to modify.
- func_update: A function that defines the update, supports async.
Example:
import asyncio
import random
import flet as ft
import flet_easy as fs
app = fs.FletEasy(route_init="/")
# remove animation on route change
@app.config
def config(page: ft.Page):
page.theme = ft.Theme(
page_transitions=ft.PageTransitionsTheme(
windows=ft.PageTransitionTheme.NONE,
android=ft.PageTransitionTheme.NONE,
ios=ft.PageTransitionTheme.NONE,
macos=ft.PageTransitionTheme.NONE,
linux=ft.PageTransitionTheme.NONE,
),
)
# use in 'data.view'
@app.view
def config_view(data: fs.Datasy):
def change_color(e: ft.ControlEvent):
colors = [ft.Colors.RED, ft.Colors.GREEN, ft.Colors.BLUE, ft.Colors.YELLOW]
appbar.bgcolor = random.choice(colors)
data.page.update()
appbar = ft.AppBar(
bgcolor=ft.Colors.BLACK45,
actions=[
ft.IconButton(
icon=ft.Icons.RESTART_ALT_ROUNDED,
icon_color=ft.Colors.WHITE,
on_click=change_color,
)
],
)
return ft.View(
appbar=appbar,
navigation_bar=ft.NavigationBar(
destinations=[
ft.NavigationBarDestination(icon=ft.Icons.CODE, label="counter 1"),
ft.NavigationBarDestination(icon=ft.Icons.SYNC_DISABLED, label="counter 2"),
ft.NavigationBarDestination(
icon=ft.Icons.CODE,
label="counter 3",
),
],
on_change=data.go_navigation_bar,
),
)
# control custom
class Counter(ft.Container):
def __init__(self, update, color: str):
super().__init__()
self.update = update
self.number = ft.TextField(value="0", text_size=50, text_align="center")
self.content = ft.Column(
controls=[
self.number,
ft.FilledButton("start", on_click=self.start, height=50),
],
horizontal_alignment="center",
)
self.width = 400
self.bgcolor = color
self.border_radius = 10
self.padding = 20
async def start(self, e):
while True:
self.number.value = str(int(self.number.value) + 1)
self.update()
await asyncio.sleep(1)
# add cache to the page
@app.page("/", title="Test 1", index=0, cache=True)
def index_page(data: fs.Datasy):
page = data.page
appbar = data.view.appbar
async def update_title(e: ft.AppBar):
e.title = ft.Text("Test 1")
data.dynamic_control(appbar, update_title)
return ft.View(
controls=[
ft.Text("Counter 1", size=50),
Counter(page.update, ft.Colors.RED),
],
appbar=appbar,
navigation_bar=data.view.navigation_bar,
horizontal_alignment="center",
vertical_alignment="center",
)
@app.page("/test2", title="Test 2", index=1)
def test_page(data: fs.Datasy):
page = data.page
appbar = data.view.appbar
appbar.title = ft.Text("Test 2")
return ft.View(
controls=[
ft.Text("Counter 2 - (cache disabled)", size=50),
Counter(page.update, ft.Colors.BLUE),
],
appbar=appbar,
navigation_bar=data.view.navigation_bar,
vertical_alignment="center",
horizontal_alignment="center",
)
# add cache to the page
@app.page("/test3", title="Test 3", index=2, cache=True)
async def test2_page(data: fs.Datasy):
page = data.page
appbar = data.view.appbar
data.dynamic_control(appbar, func_update=lambda e: setattr(e, "title", ft.Text("Test 3")))
return ft.View(
controls=[
ft.Text("Counter 3", size=50),
Counter(page.update, ft.Colors.GREEN),
],
appbar=appbar,
navigation_bar=data.view.navigation_bar,
horizontal_alignment="center",
vertical_alignment="center",
)
app.run()
🎬Demo
use-cache-page-2.mp4
Metadata
Metadata
Assignees
Labels
Projects
Status