Skip to content

bug: it is not possible to create ft.DataRow using the Declarative UI method in Flet #6160

@18909175158

Description

@18909175158

Duplicate Check

Describe the bug

Because the 'ft.Component' object has no attribute 'visible', it is not possible to create ft.DataRow using the Declarative UI method in Flet.

Code sample

Code
import flet as ft
from dataclasses import dataclass

@dataclass
@ft.observable
class RowState:
    v:str

@ft.component
def Row(state: RowState):
    return ft.DataRow(cells=[ft.DataCell(content=ft.Text(state.v))])

@dataclass
@ft.observable
class TableState:
    rows_state: list[RowState]

@ft.component
def Table(state: TableState):
    return ft.DataTable(
        columns=[ft.DataColumn(label="column 1")],
        rows=[Row(r) for r in state.rows_state]
        )

async def main(page: ft.Page):
    page.render(lambda : Table(TableState([RowState("1")])))

ft.run(main)

To reproduce

(PayrollForFastyun) C:\PythonPrograms\PayrollForFastyun>c:\PythonPrograms\PayrollForFastyun.venv\Scripts\python.exe c:/PythonPrograms/PayrollForFastyun/src/tests/page_test.py
Unhandled error in main() handler
Traceback (most recent call last):
File "c:\PythonPrograms\PayrollForFastyun.venv\Lib\site-packages\flet\app.py", line 260, in on_session_created
await main(session.page)
File "c:\PythonPrograms\PayrollForFastyun\src\tests\page_test.py", line 26, in main
page.render(lambda : Table(TableState([RowState("1")])))
~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "c:\PythonPrograms\PayrollForFastyun.venv\Lib\site-packages\flet\controls\page.py", line 429, in render
self.__render()
~~~~~~~~~~~~~^^
File "c:\PythonPrograms\PayrollForFastyun.venv\Lib\site-packages\flet\controls\page.py", line 443, in __render
self.update()
~~~~~~~~~~~^^
File "c:\PythonPrograms\PayrollForFastyun.venv\Lib\site-packages\flet\controls\page.py", line 452, in update
self.__update(self)
~~~~~~~~~~~~~^^^^^^
File "c:\PythonPrograms\PayrollForFastyun.venv\Lib\site-packages\flet\controls\page.py", line 461, in __update
self.session.patch_control(c)
~~~~~~~~~~~~~~~~~~~~~~~~~~^^^
File "c:\PythonPrograms\PayrollForFastyun.venv\Lib\site-packages\flet\messaging\session.py", line 125, in patch_control
patch, added_controls, removed_controls = self.__get_update_control_patch(
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
control=control,
^^^^^^^^^^^^^^^^
...<3 lines>...
frozen=frozen,
^^^^^^^^^^^^^^
)
^
File "c:\PythonPrograms\PayrollForFastyun.venv\Lib\site-packages\flet\messaging\session.py", line 301, in __get_update_control_patch
patch, added_controls, removed_controls = ObjectPatch.from_diff(
~~~~~~~~~~~~~~~~~~~~~^
prev_control,
^^^^^^^^^^^^^
...<4 lines>...
frozen=frozen,
^^^^^^^^^^^^^^
)
^
File "c:\PythonPrograms\PayrollForFastyun.venv\Lib\site-packages\flet\controls\object_patch.py", line 248, in from_diff
added = list(builder.get_added_controls())
File "c:\PythonPrograms\PayrollForFastyun.venv\Lib\site-packages\flet\controls\object_patch.py", line 356, in get_added_controls
yield from self._configure_dataclass(
dc, None, False, configure_setattr_only
)
File "c:\PythonPrograms\PayrollForFastyun.venv\Lib\site-packages\flet\controls\object_patch.py", line 1196, in _configure_dataclass
yield from self._configure_dataclass(
getattr(item, field.name), item, frozen
)
File "c:\PythonPrograms\PayrollForFastyun.venv\Lib\site-packages\flet\controls\object_patch.py", line 1188, in _configure_dataclass
item._before_update_safe()
~~~~~~~~~~~~~~~~~~~~~~~~^^
File "c:\PythonPrograms\PayrollForFastyun.venv\Lib\site-packages\flet\controls\base_control.py", line 233, in _before_update_safe
self.before_update()
~~~~~~~~~~~~~~~~~~^^
File "c:\PythonPrograms\PayrollForFastyun.venv\Lib\site-packages\flet\controls\material\datatable.py", line 531, in before_update
visible_rows = list(filter(lambda row: row.visible, self.rows))
File "c:\PythonPrograms\PayrollForFastyun.venv\Lib\site-packages\flet\controls\material\datatable.py", line 531, in
visible_rows = list(filter(lambda row: row.visible, self.rows))
^^^^^^^^^^^
AttributeError: 'Component' object has no attribute 'visible'

Expected behavior

I tried to use ft.DataRow as a regular component:

import flet as ft
from dataclasses import dataclass

@dataclass
# observable mode is not used here
# @ft.observable
class RowState:
    v:str

# Common components are used here
# @ft.component
def Row(state: RowState):
    return ft.DataRow(cells=[ft.DataCell(content=ft.Text(state.v))])

@dataclass
@ft.observable
class TableState:
    rows_state: list[RowState]

@ft.component
def Table(state: TableState):
    return ft.DataTable(
        columns=[ft.DataColumn(label="column 1")],
        rows=[Row(r) for r in state.rows_state]
        )

async def main(page: ft.Page):
    page.render(lambda : Table(TableState([RowState("1")])))

ft.run(main)

But:

  1. When updating the RowState of a single row individually, it does not trigger a re-render, and flet cannot detect the update of the child items of TableState.
  2. If delete an old RowState and then add a new RowState, it triggers a full re-render of the entire table instead of just rendering the changed rows, leading to performance issues.

Screenshots / Videos

Captures Image

Operating System

Windows

Operating system details

windows 10 (AMD64)

Flet version

Flet: 0.80.5 Flutter: 3.38.7 Pyodide: 0.27.7 Python 3.14.0

Regression

No, it isn't

Suggestions

No response

Logs

Logs
Unhandled error in main() handler
Traceback (most recent call last):
  File "c:\PythonPrograms\PayrollForFastyun\.venv\Lib\site-packages\flet\app.py", line 260, in on_session_created
    await main(session.page)
  File "c:\PythonPrograms\PayrollForFastyun\src\tests\page_test.py", line 26, in main
    page.render(lambda : Table(TableState([RowState("1")])))
    ~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "c:\PythonPrograms\PayrollForFastyun\.venv\Lib\site-packages\flet\controls\page.py", line 429, in render
    self.__render()
    ~~~~~~~~~~~~~^^
  File "c:\PythonPrograms\PayrollForFastyun\.venv\Lib\site-packages\flet\controls\page.py", line 443, in __render
    self.update()
    ~~~~~~~~~~~^^
  File "c:\PythonPrograms\PayrollForFastyun\.venv\Lib\site-packages\flet\controls\page.py", line 452, in update
    self.__update(self)
    ~~~~~~~~~~~~~^^^^^^
  File "c:\PythonPrograms\PayrollForFastyun\.venv\Lib\site-packages\flet\controls\page.py", line 461, in __update
    self.session.patch_control(c)
    ~~~~~~~~~~~~~~~~~~~~~~~~~~^^^
  File "c:\PythonPrograms\PayrollForFastyun\.venv\Lib\site-packages\flet\messaging\session.py", line 125, in patch_control
    patch, added_controls, removed_controls = self.__get_update_control_patch(
                                              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
        control=control,
        ^^^^^^^^^^^^^^^^
    ...<3 lines>...
        frozen=frozen,
        ^^^^^^^^^^^^^^
    )
    ^
  File "c:\PythonPrograms\PayrollForFastyun\.venv\Lib\site-packages\flet\messaging\session.py", line 301, in __get_update_control_patch
    patch, added_controls, removed_controls = ObjectPatch.from_diff(    
                                              ~~~~~~~~~~~~~~~~~~~~~^    
        prev_control,
        ^^^^^^^^^^^^^
    ...<4 lines>...
        frozen=frozen,
        ^^^^^^^^^^^^^^
    )
    ^
  File "c:\PythonPrograms\PayrollForFastyun\.venv\Lib\site-packages\flet\controls\object_patch.py", line 248, in from_diff
    added = list(builder.get_added_controls())
  File "c:\PythonPrograms\PayrollForFastyun\.venv\Lib\site-packages\flet\controls\object_patch.py", line 356, in get_added_controls
    yield from self._configure_dataclass(
        dc, None, False, configure_setattr_only
    )
  File "c:\PythonPrograms\PayrollForFastyun\.venv\Lib\site-packages\flet\controls\object_patch.py", line 1196, in _configure_dataclass
    yield from self._configure_dataclass(
        getattr(item, field.name), item, frozen
    )
  File "c:\PythonPrograms\PayrollForFastyun\.venv\Lib\site-packages\flet\controls\object_patch.py", line 1188, in _configure_dataclass
    item._before_update_safe()
    ~~~~~~~~~~~~~~~~~~~~~~~~^^
  File "c:\PythonPrograms\PayrollForFastyun\.venv\Lib\site-packages\flet\controls\base_control.py", line 233, in _before_update_safe
    self.before_update()
    ~~~~~~~~~~~~~~~~~~^^
  File "c:\PythonPrograms\PayrollForFastyun\.venv\Lib\site-packages\flet\controls\material\datatable.py", line 531, in before_update
    visible_rows = list(filter(lambda row: row.visible, self.rows))     
  File "c:\PythonPrograms\PayrollForFastyun\.venv\Lib\site-packages\flet\controls\material\datatable.py", line 531, in <lambda>
    visible_rows = list(filter(lambda row: row.visible, self.rows))     
                                           ^^^^^^^^^^^
AttributeError: 'Component' object has no attribute 'visible'

Additional details

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions