flet icon indicating copy to clipboard operation
flet copied to clipboard

bug: RuntimeError: Frozen controls cannot be updated.

Open aigcst opened this issue 1 month ago • 2 comments

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 normally
import 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

aigcst avatar Nov 20 '25 14:11 aigcst

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))

GreenDringo42 avatar Nov 21 '25 00:11 GreenDringo42

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))

aigcst avatar Nov 26 '25 15:11 aigcst