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
modelproperty before I set thecallbacksinstance 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...