AttributeError when inheriting from DataTable #1091
-
QuestionI am in the process of writing an extension of When I try to run the code sample below, I get an AttributeError, telling me that What am I missing/doing wrong? Code samplefrom dataclasses import asdict, dataclass
from typing import Any, Callable, Optional, Union
import flet as ft
import polars
from flet_core.gradients import Gradient
from flet_core.types import (
AnimationValue,
BorderRadiusValue,
OffsetValue,
ResponsiveNumber,
RotateValue,
ScaleValue,
)
@dataclass
class DataTableConfig:
ref: Optional[ft.Ref] = None
width: ft.OptionalNumber = None
height: ft.OptionalNumber = None
left: ft.OptionalNumber = None
top: ft.OptionalNumber = None
right: ft.OptionalNumber = None
bottom: ft.OptionalNumber = None
expand: Union[None, bool, int] = None
col: Optional[ResponsiveNumber] = None
opacity: ft.OptionalNumber = None
rotate: RotateValue = None
scale: ScaleValue = None
offset: OffsetValue = None
aspect_ratio: ft.OptionalNumber = None
animate_opacity: AnimationValue = None
animate_size: AnimationValue = None
animate_position: AnimationValue = None
animate_rotation: AnimationValue = None
animate_scale: AnimationValue = None
animate_offset: AnimationValue = None
on_animation_end = None
tooltip: Optional[str] = None
visible: Optional[bool] = None
disabled: Optional[bool] = None
data: Any = None
border: Optional[ft.Border] = None
border_radius: BorderRadiusValue = None
horizontal_lines: Optional[ft.BorderSide] = None
vertical_lines: Optional[ft.BorderSide] = None
checkbox_horizontal_margin: ft.OptionalNumber = None
column_spacing: ft.OptionalNumber = None
data_row_color: Union[None, str, dict[ft.MaterialState, str]] = None
data_row_height: ft.OptionalNumber = None
data_text_style: Optional[ft.TextStyle] = None
bgcolor: Optional[str] = None
gradient: Optional[Gradient] = None
divider_thickness: ft.OptionalNumber = None
heading_row_color: Union[None, str, dict[ft.MaterialState, str]] = None
heading_row_height: ft.OptionalNumber = None
heading_text_style: Optional[ft.TextStyle] = None
horizontal_margin: ft.OptionalNumber = None
show_bottom_border: Optional[bool] = None
show_checkbox_column: Optional[bool] = None
sort_ascending: Optional[bool] = None
sort_column_index: Optional[int] = None
on_select_all = None
@dataclass
class TableCallbackConfig:
# row callbacks
on_select_changed_row: Callable | None = None
on_long_press_row: Callable | None = None
# cell callbacks
on_long_press_cell: Callable | None = None
on_tap_cell: Callable | None = None
on_double_tap_cell: Callable | None = None
on_tap_cancel_cell: Callable | None = None
on_tap_down_cell: Callable | None = None
# column callbacks
on_sort_column: Callable | None = None
class ModelDataTable(ft.DataTable):
def __init__(
self,
*,
model: polars.DataFrame,
table_config: DataTableConfig = DataTableConfig(),
call_back_config: TableCallbackConfig = TableCallbackConfig(),
) -> None:
self.model = model
self.callbacks = call_back_config
super().__init__(**asdict(table_config))
@property
def model(self) -> polars.DataFrame:
return self._model
@model.setter
def model(self, model: polars.DataFrame) -> None:
self._model = model
self._render_model()
def _render_model(self) -> None:
self.columns = [
ft.DataColumn(ft.Text(column), on_sort=self.callbacks.on_sort_column)
for column in self._model.columns
]
self.rows = [
ft.DataRow(
[self._get_cell(cell) for cell in row],
on_select_changed=self.callbacks.on_select_changed_row,
on_long_press=self.callbacks.on_long_press_row,
)
for row in self._model.rows()
]
if self.page:
self.page.update()
def _get_cell(self, text: str) -> ft.DataCell:
return ft.DataCell(
ft.Text(text),
on_long_press=self.callbacks.on_long_press_cell,
on_tap=self.callbacks.on_tap_cell,
on_double_tap=self.callbacks.on_double_tap_cell,
on_tap_cancel=self.callbacks.on_tap_cancel_cell,
on_tap_down=self.callbacks.on_tap_down_cell,
)
def main(page: ft.Page):
model = polars.read_csv(
file="https://raw.githubusercontent.com/iron3oxide/ndcc/main/ndcc/data/charts.csv",
infer_schema_length=300,
)
table_config = DataTableConfig(show_checkbox_column=True, expand=True)
callback_config = TableCallbackConfig(on_select_changed_row=lambda: print("click"))
table = ModelDataTable(
model=model, table_config=table_config, call_back_config=callback_config
)
page.scroll = ft.ScrollMode.ADAPTIVE
page.add(ft.Column(controls=[table]))
page.update()
ft.app(target=main) Error messageUnhandled error processing page session : Traceback (most recent call last):
File "/home/jason/PycharmProjects/fletched/.venv/lib/python3.11/site-packages/flet/flet.py", line 300, in on_session_created
session_handler(page)
File "/home/jason/PycharmProjects/fletched/fletched/controls/datatable.py", line 142, in main
table = ModelDataTable(
^^^^^^^^^^^^^^^
File "/home/jason/PycharmProjects/fletched/fletched/controls/datatable.py", line 90, in __init__
self.model = model
^^^^^^^^^^
File "/home/jason/PycharmProjects/fletched/fletched/controls/datatable.py", line 102, in model
self._render_model()
File "/home/jason/PycharmProjects/fletched/fletched/controls/datatable.py", line 105, in _render_model
self.columns = [
^
File "/home/jason/PycharmProjects/fletched/fletched/controls/datatable.py", line 106, in <listcomp>
ft.DataColumn(ft.Text(column), on_sort=self.callbacks.on_sort_column)
^^^^^^^^^^^^^^
AttributeError: 'ModelDataTable' object has no attribute 'callbacks' ------------------------------------------------------
|
Beta Was this translation helpful? Give feedback.
Replies: 1 comment
-
Nevermind, found my mistake 🤦♂️. For those interested: I called the |
Beta Was this translation helpful? Give feedback.
Nevermind, found my mistake 🤦♂️. For those interested: I called the
model
property before I set thecallbacks
instance variable, so of course the attribute was unknown. Also I had to move thesuper().__init__()
call to the top so the property would have a page attribute to access. Silly me...