Problem mit MDDataTable

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
DMD-OL
User
Beiträge: 315
Registriert: Samstag 26. Dezember 2015, 16:21

Ich habe mit Internethilfe eine MDDataTable eine Tabelle mit 3 Zeilen erstellt.
Jetzt will ich per Klick auf die Zeile (erstmal nicht mit Klick auf Checkbutton) diejenige aus der Tabelle löschen und die verbleibenen dann wider anzeigen.
(Der Code ist vollständig und direkt verwendbar :)

Code: Alles auswählen

from kivymd.uix.button import MDFillRoundFlatButton
from kivymd.uix.screen import MDScreen
from kivymd.uix.toolbar import MDToolbar
from kivy.metrics import dp
from kivymd.app import MDApp
from kivymd.uix.datatables import MDDataTable
from kivy.clock import Clock


class App(MDApp):
    def __init__(self):  # **kwargs
        super().__init__()  # **kwargs
        self.btn_hide = False
        self.screen, self.table = None, None
        self.selected = []

        self.btn_delete = MDFillRoundFlatButton(
            text="Übertragen",
            pos_hint={'center_x': 0.8, 'center_y': 0.15},
            size_hint=(0.2, 0.1),
            font_size=20,
            opacity=1,
            on_press=self.delete)

        """
        self.btn_transfer = MDFillRoundFlatButton(
            text="Übertragen",
            pos_hint={'center_x': 0.8, 'center_y': 0.15},
            size_hint=(0.2, 0.1),
            font_size=20,
            opacity=1,
            on_press=self.transfer)
        """

        self.tbl_list = [
            ["1", "10.07.2022", "John", "Elder", "john@codemy.com", "(123) 456-7891"],
            ["2", "11.07.2022", "Mary", "Elder", "mary@codemy.com", "(123) 456-7892"],
            ["3", "12.07.2022", "Rose", "Elder", "rose@codemy.com", "(123) 456-7893"],
        ]

    def build(self):
        self.screen = MDScreen()
        self.theme_cls.theme_style = "Dark"
        self.theme_cls.primary_palette = "BlueGray"

        toolbar = MDToolbar(title="Test")
        toolbar.pos_hint = {"top": 1}
        # toolbar.right_action_items = [["rotate-3d-variant"]]
        self.screen.add_widget(toolbar)

        self.table = MDDataTable(
            size_hint=(0.95, 0.6),
            pos_hint={'center_x': 0.5, 'center_y': 0.55},
            rows_num=100,
            check=True,
            use_pagination=False,
            background_color_header="#545454",
            background_color_selected_cell="#545454",
            column_data=[
                ["Nr.", dp(20)],
                ["Date", dp(20)],
                ["First name", dp(20)],
                ["Last name", dp(20)],
                ["E-Mail Address", dp(38)],
                ["Phone Number", dp(34)]],
            row_data=self.tbl_list)

        self.table.bind(on_row_press=self.on_row_press)
        # self.table.bind(on_check_press=self.on_check_press)

        self.screen.add_widget(self.table)
        self.screen.add_widget(self.btn_delete)
        return self.screen

    def on_check_press(self, table, _):
        table.unbind(on_row_press=self.on_row_press)
        Clock.schedule_once(self.binding_event_table_row_press, 0.5)

    def binding_event_table_row_press(self, _):
        self.table.bind(on_row_press=self.on_row_press)

    def on_row_press(self, table, row):
        index = row.index
        cols_num = len(table.column_data)
        row_num = int(index / cols_num)
        # col_num = index % cols_num
        cell_row = table.table_data.view_adapter.get_visible_view(row_num * cols_num)
        if cell_row.ids.check.state == 'normal':
            row.ids.check.state = 'down'
            cell_row.change_check_state_no_notify("down")
            if row_num not in self.selected:
                self.selected.append(row_num)
        else:
            row.ids.check.state = 'normal'
            cell_row.change_check_state_no_notify("normal")
            if row_num in self.selected:
                self.selected.remove(row)
        table.table_data.on_mouse_select(row)

    def delete(self, _):
        for row in self.selected:
            del self.tbl_list[row]

        del self.selected[:]
        self.table.row_data = self.tbl_list
        self.table.table_data.select_all('normal')


if __name__ == '__main__':
    App().run()
Mit Klick auf Löschen erhalte ich die Fehlermeldung:

Code: Alles auswählen

 Traceback (most recent call last):
   File "C:\Users\chris\Documents\Programmierung\PyCharm\Privat\Kostenverwaltung\kw_main_3.py", line 129, in <module>
     App().run()
   File "C:\Program Files\Python37\lib\site-packages\kivy\app.py", line 950, in run
     runTouchApp()
   File "C:\Program Files\Python37\lib\site-packages\kivy\base.py", line 582, in runTouchApp
     EventLoop.mainloop()
   File "C:\Program Files\Python37\lib\site-packages\kivy\base.py", line 347, in mainloop
     self.idle()
   File "C:\Program Files\Python37\lib\site-packages\kivy\base.py", line 391, in idle
     self.dispatch_input()
   File "C:\Program Files\Python37\lib\site-packages\kivy\base.py", line 342, in dispatch_input
     post_dispatch_input(*pop(0))
   File "C:\Program Files\Python37\lib\site-packages\kivy\base.py", line 248, in post_dispatch_input
     listener.dispatch('on_motion', etype, me)
   File "kivy\_event.pyx", line 709, in kivy._event.EventDispatcher.dispatch
   File "C:\Program Files\Python37\lib\site-packages\kivy\core\window\__init__.py", line 1412, in on_motion
     self.dispatch('on_touch_down', me)
   File "kivy\_event.pyx", line 709, in kivy._event.EventDispatcher.dispatch
   File "C:\Program Files\Python37\lib\site-packages\kivy\core\window\__init__.py", line 1428, in on_touch_down
     if w.dispatch('on_touch_down', touch):
   File "kivy\_event.pyx", line 709, in kivy._event.EventDispatcher.dispatch
   File "C:\Program Files\Python37\lib\site-packages\kivy\uix\relativelayout.py", line 297, in on_touch_down
     ret = super(RelativeLayout, self).on_touch_down(touch)
   File "C:\Program Files\Python37\lib\site-packages\kivy\uix\widget.py", line 545, in on_touch_down
     if child.dispatch('on_touch_down', touch):
   File "kivy\_event.pyx", line 709, in kivy._event.EventDispatcher.dispatch
   File "C:\Program Files\Python37\lib\site-packages\kivymd\uix\button\button.py", line 931, in on_touch_down
     return super().on_touch_down(touch)
   File "C:\Program Files\Python37\lib\site-packages\kivymd\uix\behaviors\ripple_behavior.py", line 352, in on_touch_down
     super().on_touch_down(touch)
   File "C:\Program Files\Python37\lib\site-packages\kivy\uix\behaviors\button.py", line 151, in on_touch_down
     self.dispatch('on_press')
   File "kivy\_event.pyx", line 705, in kivy._event.EventDispatcher.dispatch
   File "kivy\_event.pyx", line 1248, in kivy._event.EventObservers.dispatch
   File "kivy\_event.pyx", line 1172, in kivy._event.EventObservers._dispatch
   File "C:\Users\chris\Documents\Programmierung\PyCharm\Privat\Kostenverwaltung\kw_main_3.py", line 125, in delete
     self.table.table_data.select_all('normal')
   File "C:\Program Files\Python37\lib\site-packages\kivymd\uix\datatables\datatables.py", line 614, in select_all
     self.on_mouse_select(cell_row_obj)
   File "C:\Program Files\Python37\lib\site-packages\kivymd\uix\datatables\datatables.py", line 706, in on_mouse_select
     self.ids.row_controller.select_current(self)
   File "C:\Program Files\Python37\lib\site-packages\kivymd\uix\datatables\datatables.py", line 136, in select_current
     last, nodes = self.get_nodes()
   File "C:\Program Files\Python37\lib\site-packages\kivymd\uix\datatables\datatables.py", line 113, in get_nodes
     self.clear_selection()
   File "C:\Program Files\Python37\lib\site-packages\kivy\uix\behaviors\compoundselection.py", line 534, in clear_selection
     deselect(node)
   File "C:\Program Files\Python37\lib\site-packages\kivy\uix\recycleview\layout.py", line 109, in deselect_node
     self.apply_selection(node, view, False)
   File "C:\Program Files\Python37\lib\site-packages\kivy\uix\recycleview\layout.py", line 143, in apply_selection
     view.apply_selection(self.recycleview, index, is_selected)
   File "C:\Program Files\Python37\lib\site-packages\kivymd\uix\datatables\datatables.py", line 1803, in apply_selection
     ic = instance_table_data.recycle_data[index].get("icon", None)
 IndexError: list index out of range

Process finished with exit code 1
Leider fehlt mir das Verständnis den Fehler zu verstehen.
Für mich ist da alles richtig. Kann mir da bitte jmd. helfen...?
Benutzeravatar
sparrow
User
Beiträge: 4164
Registriert: Freitag 17. April 2009, 10:28

Das ist nicht lauffähig, wenn du nicht die Requirements mitlieferst.
"MDToolbar" gibt es schon eine Weile nicht mehr in kivymd.
DMD-OL
User
Beiträge: 315
Registriert: Samstag 26. Dezember 2015, 16:21

Wenn ich das hier mache

Code: Alles auswählen

    def delete(self, table, row):
        for row in self.selected:
            del self.tbl_list[row]

        del self.selected[:]
        self.table.row_data = self.tbl_list
        self.table.table_data.select_all('normal')
bekomm ich die Fehlermeldung:

Code: Alles auswählen

 TypeError: delete() missing 1 required positional argument: 'row'
Wieso positional argument?
Benutzeravatar
__blackjack__
User
Beiträge: 13003
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@DMD-OL: Ich verstehe die Frage nicht‽ Da sind ja nur positional Argumente. Warum heissen die `table` und `row`? Weisst Du was da *tatsächlich* übergeben wird? Beide werden ja auch überhaupt gar nicht verwendet.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
DMD-OL
User
Beiträge: 315
Registriert: Samstag 26. Dezember 2015, 16:21

ne, deswegen frage ich ja hier. Keine Ahnung was da tatsächlich übergeben werden muß.
Auch das hier geht nicht

Code: Alles auswählen

    def delete(self, table, row):
        print(table, row)
Auch hier fehlt ein Argument

Code: Alles auswählen

 TypeError: delete() missing 1 required positional argument: 'row'
Sirius3
User
Beiträge: 17710
Registriert: Sonntag 21. Oktober 2012, 17:20

Du übergibst da gar nichts, `delete` wird als Eventhandler von on_press aufgerufen, und das hat halt nur ein Argument, das Event. Keine Ahnung, wie Du darauf kommst, dass da table und row übergeben werden.
Antworten