-
Notifications
You must be signed in to change notification settings - Fork 617
Description
Duplicate Check
- I have searched the opened issues and there are no duplicates
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:
- 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.
- 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
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
