bug: RuntimeError: Frozen controls cannot be updated.
Duplicate Check
- [x] I have searched the opened issues and there are no duplicates
Describe the bug
The previous modes cannot be mixed in the Declarative UI. #5342 Many of the contents inside have changed
Code sample
Code
Code that runs normallyimport flet as ft
@ft.component
def App():
count, set_count = ft.use_state(0)
is_hoved, set_is_hoved = ft.use_state(0)
def change_color(e):
set_is_hoved(not is_hoved)
return ft.Row(
controls=[
ft.Text(value=f"{count}"),
ft.Button(
"Add",
bgcolor=ft.Colors.BLUE if is_hoved else ft.Colors.RED,
on_click=lambda: set_count(count + 1),
on_hover=change_color,
),
],
)
ft.run(lambda page: page.render(App))
Code that throws an error when hovered over
import flet as ft
@ft.component
def App():
count, set_count = ft.use_state(0)
def change_color(e):
e.control.bgcolor = ft.Colors.BLUE if e.data else ft.Colors.RED
return ft.Row(
controls=[
ft.Text(value=f"{count}"),
ft.Button(
"Add",
bgcolor=ft.Colors.RED,
on_click=lambda: set_count(count + 1),
on_hover=change_color,
),
],
)
ft.run(lambda page: page.render(App))
To reproduce
Steps to reproduce: 1.Run the repro code. 2.When hovering over the button, an error is reported: RuntimeError: Frozen controls cannot be updated.
Expected behavior
Can imperative UI be used normally in Declarative UI (or can they be mixed and used)? I expect both forms to work properly.
Screenshots / Videos
Captures
[Upload media here]
Operating System
Windows
Operating system details
windows 11
Flet version
0.70.0.dev6735
Regression
I'm not sure / I don't know
Suggestions
No response
Logs
Logs
[Paste your logs here]
Additional details
No response
Now you have to use ft.use_state to change properties in widgets. This is because widgets are now immutable and can only be re-rendered with changes in the state.
import flet as ft
@ft.component
def App():
count, set_count = ft.use_state(0)
hovered, set_hovered = ft.use_state(False)
def on_hover(e):
set_hovered(e.data) # True / False
return ft.Row(
controls=[
ft.Text(value=str(count)),
ft.Button(
"Add",
bgcolor=ft.Colors.BLUE if hovered else ft.Colors.RED,
on_click=lambda e: set_count(count + 1),
on_hover=on_hover,
),
],
)
ft.run(lambda page: page.render(App))
Is there no mixed mode? If it cannot be mixed, UI customization is basically impossible, and most existing libraries cannot be effectively used
import flet as ft
from dataclasses import dataclass
from typing import Optional, Any
@dataclass
class MyButton(ft.Button):
def __post_init__(self, ref: Optional[ft.Ref[Any]]):
self.bgcolor = ft.Colors.BLUE
self.on_hover = self.change_color
return super().__post_init__(ref)
def change_color(self, e):
self.bgcolor = ft.Colors.RED if e.data == "true" else ft.Colors.BLUE
@ft.component
def App():
count, set_count = ft.use_state(0)
return ft.Row(
controls=[
ft.Text(value=f"{count}"),
MyButton(
"Add",
on_click=lambda: set_count(count + 1),
),
],
)
ft.run(lambda page: page.render(App))