KivyMD
KivyMD copied to clipboard
[Bug] datatables' on_check_press Does not return MDI content for use with remove_row or other
https://github.com/kivymd/KivyMD/blob/82cde89a4b055f70b983b791592d8554c404615a/kivymd/uix/datatables/datatables.py#L1492
Description of the Bug
The provided example in the markup contains row_data with values such as ("alert", [255 / 256, 165 / 256, 0, 1], "No Signal") which doesn't return properly from the on_check_press or on_row_press. This results in a scenario where you will never be able to remove the row when you submit to remove_row
def on_check_press(self, instance_table, current_row):
'''Called when the check box in the table row is checked.'''
self.data_tables.remove_row(tuple(current_row))
Versions
- OS: Ubuntu 20.04
- Python: 3.8.10
- Kivy: v2.1.0
- KivyMD: commit @ e0e4870
The description of the behavior is not reproduced.
from kivy.metrics import dp
from kivymd.app import MDApp
from kivymd.uix.datatables import MDDataTable
from kivymd.uix.screen import MDScreen
class Example(MDApp):
def build(self):
self.data_tables = MDDataTable(
use_pagination=True,
check=True,
column_data=[
("No.", dp(30)),
("Status", dp(30)),
("Signal Name", dp(60), self.sort_on_signal),
("Severity", dp(30)),
("Stage", dp(30)),
("Schedule", dp(30), self.sort_on_schedule),
("Team Lead", dp(30), self.sort_on_team),
],
row_data=[
(
"1",
("alert", [255 / 256, 165 / 256, 0, 1], "No Signal"),
"Astrid: NE shared managed",
"Medium",
"Triaged",
"0:33",
"Chase Nguyen",
),
(
"2",
("alert-circle", [1, 0, 0, 1], "Offline"),
"Cosmo: prod shared ares",
"Huge",
"Triaged",
"0:39",
"Brie Furman",
),
(
"3",
(
"checkbox-marked-circle",
[39 / 256, 174 / 256, 96 / 256, 1],
"Online",
),
"Phoenix: prod shared lyra-lists",
"Minor",
"Not Triaged",
"3:12",
"Jeremy lake",
),
(
"4",
(
"checkbox-marked-circle",
[39 / 256, 174 / 256, 96 / 256, 1],
"Online",
),
"Sirius: NW prod shared locations",
"Negligible",
"Triaged",
"13:18",
"Angelica Howards",
),
(
"5",
(
"checkbox-marked-circle",
[39 / 256, 174 / 256, 96 / 256, 1],
"Online",
),
"Sirius: prod independent account",
"Negligible",
"Triaged",
"22:06",
"Diane Okuma",
),
],
sorted_on="Schedule",
sorted_order="ASC",
elevation=2,
)
self.data_tables.bind(on_row_press=self.on_row_press)
self.data_tables.bind(on_check_press=self.on_check_press)
screen = MDScreen()
screen.add_widget(self.data_tables)
return screen
def on_row_press(self, instance_table, instance_row):
'''Called when a table row is clicked.'''
print(instance_table, instance_row)
def on_check_press(self, instance_table, current_row):
'''Called when the check box in the table row is checked.'''
self.data_tables.remove_row(tuple(current_row))
# Sorting Methods:
# since the https://github.com/kivymd/KivyMD/pull/914 request, the
# sorting method requires you to sort out the indexes of each data value
# for the support of selections.
#
# The most common method to do this is with the use of the builtin function
# zip and enumerate, see the example below for more info.
#
# The result given by these funcitons must be a list in the format of
# [Indexes, Sorted_Row_Data]
def sort_on_signal(self, data):
return zip(*sorted(enumerate(data), key=lambda l: l[1][2]))
def sort_on_schedule(self, data):
return zip(
*sorted(
enumerate(data),
key=lambda l: sum(
[
int(l[1][-2].split(":")[0]) * 60,
int(l[1][-2].split(":")[1]),
]
),
)
)
def sort_on_team(self, data):
return zip(*sorted(enumerate(data), key=lambda l: l[1][-1]))
Example().run()
[INFO ] [Logger ] Record log in /home/administrator/.kivy/logs/kivy_22-03-11_1.txt
[INFO ] [Kivy ] v2.1.0
[INFO ] [Kivy ] Installed at "/home/administrator/Documents/app/env/lib/python3.8/site-packages/kivy/__init__.py"
[INFO ] [Python ] v3.8.10 (default, Nov 26 2021, 20:14:08)
[GCC 9.3.0]
[INFO ] [Python ] Interpreter at "/home/administrator/Documents/app/env/bin/python3"
[INFO ] [Logger ] Purge log fired. Processing...
[INFO ] [Logger ] Purge finished!
[INFO ] [KivyMD ] 1.0.0.dev0, git-e0e4870, 2022-03-08 (installed at "/home/administrator/Documents/app/env/lib/python3.8/site-packages/kivymd/__init__.py")
[INFO ] [Factory ] 189 symbols loaded
[INFO ] [Image ] Providers: img_tex, img_dds, img_sdl2, img_pil (img_ffpyplayer ignored)
[INFO ] [Text ] Provider: sdl2
[INFO ] [Window ] Provider: sdl2
[INFO ] [GL ] Using the "OpenGL" graphics system
[INFO ] [GL ] Backend used <sdl2>
[INFO ] [GL ] OpenGL version <b'4.6 (Compatibility Profile) Mesa 21.2.6'>
[INFO ] [GL ] OpenGL vendor <b'Intel'>
[INFO ] [GL ] OpenGL renderer <b'Mesa Intel(R) Xe Graphics (TGL GT2)'>
[INFO ] [GL ] OpenGL parsed version: 4, 6
[INFO ] [GL ] Shading version <b'4.60'>
[INFO ] [GL ] Texture max size <16384>
[INFO ] [GL ] Texture max units <32>
[INFO ] [Window ] auto add sdl2 input provider
[INFO ] [Window ] virtual keyboard not allowed, single mode, not docked
[INFO ] [GL ] NPOT texture support is available
[WARNING] Deprecated property "<OptionProperty name=theme_text_color>" of object "<kivymd.uix.datatables.datatables.SortButton object at 0x7f1097efb740>" was accessed, it will be removed in a future version
[WARNING] Deprecated property "<ColorProperty name=text_color>" of object "<kivymd.uix.datatables.datatables.SortButton object at 0x7f1097efb740>" was accessed, it will be removed in a future version
[WARNING] Deprecated property "<NumericProperty name=user_font_size>" of object "<kivymd.uix.datatables.datatables.SortButton object at 0x7f1097efb740>" was accessed, it will be removed in a future version
[INFO ] [ProbeSysfs ] device match: /dev/input/event11
[INFO ] [MTD ] Read event from </dev/input/event11>
[INFO ] [Base ] Start application main loop
[INFO ] [Base ] Leaving application in progress...
Traceback (most recent call last):
File "./test.py", line 132, in <module>
Example().run()
File "/home/administrator/Documents/app/env/lib/python3.8/site-packages/kivy/app.py", line 955, in run
runTouchApp()
File "/home/administrator/Documents/app/env/lib/python3.8/site-packages/kivy/base.py", line 574, in runTouchApp
EventLoop.mainloop()
File "/home/administrator/Documents/app/env/lib/python3.8/site-packages/kivy/base.py", line 339, in mainloop
self.idle()
File "/home/administrator/Documents/app/env/lib/python3.8/site-packages/kivy/base.py", line 383, in idle
self.dispatch_input()
File "/home/administrator/Documents/app/env/lib/python3.8/site-packages/kivy/base.py", line 334, in dispatch_input
post_dispatch_input(*pop(0))
File "/home/administrator/Documents/app/env/lib/python3.8/site-packages/kivy/base.py", line 263, in post_dispatch_input
listener.dispatch('on_motion', etype, me)
File "kivy/_event.pyx", line 731, in kivy._event.EventDispatcher.dispatch
File "/home/administrator/Documents/app/env/lib/python3.8/site-packages/kivy/core/window/__init__.py", line 1664, in on_motion
self.dispatch('on_touch_up', me)
File "kivy/_event.pyx", line 731, in kivy._event.EventDispatcher.dispatch
File "/home/administrator/Documents/app/env/lib/python3.8/site-packages/kivy/core/window/__init__.py", line 1701, in on_touch_up
if w.dispatch('on_touch_up', touch):
File "kivy/_event.pyx", line 731, in kivy._event.EventDispatcher.dispatch
File "/home/administrator/Documents/app/env/lib/python3.8/site-packages/kivy/uix/relativelayout.py", line 322, in on_touch_up
ret = super(RelativeLayout, self).on_touch_up(touch)
File "/home/administrator/Documents/app/env/lib/python3.8/site-packages/kivy/uix/widget.py", line 611, in on_touch_up
if child.dispatch('on_touch_up', touch):
File "kivy/_event.pyx", line 731, in kivy._event.EventDispatcher.dispatch
File "/home/administrator/Documents/app/env/lib/python3.8/site-packages/kivy/uix/widget.py", line 611, in on_touch_up
if child.dispatch('on_touch_up', touch):
File "kivy/_event.pyx", line 731, in kivy._event.EventDispatcher.dispatch
File "/home/administrator/Documents/app/env/lib/python3.8/site-packages/kivymd/uix/behaviors/ripple_behavior.py", line 311, in on_touch_up
return super().on_touch_up(touch)
File "/home/administrator/Documents/app/env/lib/python3.8/site-packages/kivy/uix/behaviors/button.py", line 163, in on_touch_up
return super(ButtonBehavior, self).on_touch_up(touch)
File "/home/administrator/Documents/app/env/lib/python3.8/site-packages/kivy/uix/widget.py", line 611, in on_touch_up
if child.dispatch('on_touch_up', touch):
File "kivy/_event.pyx", line 731, in kivy._event.EventDispatcher.dispatch
File "/home/administrator/Documents/app/env/lib/python3.8/site-packages/kivy/uix/scrollview.py", line 968, in on_touch_up
if self.dispatch('on_scroll_stop', touch):
File "kivy/_event.pyx", line 731, in kivy._event.EventDispatcher.dispatch
File "/home/administrator/Documents/app/env/lib/python3.8/site-packages/kivy/uix/scrollview.py", line 1005, in on_scroll_stop
self.simulate_touch_down(touch)
File "/home/administrator/Documents/app/env/lib/python3.8/site-packages/kivy/uix/scrollview.py", line 668, in simulate_touch_down
ret = super(ScrollView, self).on_touch_down(touch)
File "/home/administrator/Documents/app/env/lib/python3.8/site-packages/kivy/uix/widget.py", line 589, in on_touch_down
if child.dispatch('on_touch_down', touch):
File "kivy/_event.pyx", line 731, in kivy._event.EventDispatcher.dispatch
File "/home/administrator/Documents/app/env/lib/python3.8/site-packages/kivy/uix/behaviors/focus.py", line 464, in on_touch_down
return super(FocusBehavior, self).on_touch_down(touch)
File "/home/administrator/Documents/app/env/lib/python3.8/site-packages/kivy/uix/widget.py", line 589, in on_touch_down
if child.dispatch('on_touch_down', touch):
File "kivy/_event.pyx", line 731, in kivy._event.EventDispatcher.dispatch
File "/home/administrator/Documents/app/env/lib/python3.8/site-packages/kivymd/uix/datatables/datatables.py", line 1737, in on_touch_down
if super().on_touch_down(touch):
File "/home/administrator/Documents/app/env/lib/python3.8/site-packages/kivy/uix/behaviors/button.py", line 138, in on_touch_down
if super(ButtonBehavior, self).on_touch_down(touch):
File "/home/administrator/Documents/app/env/lib/python3.8/site-packages/kivy/uix/widget.py", line 589, in on_touch_down
if child.dispatch('on_touch_down', touch):
File "kivy/_event.pyx", line 731, in kivy._event.EventDispatcher.dispatch
File "/home/administrator/Documents/app/env/lib/python3.8/site-packages/kivy/uix/widget.py", line 589, in on_touch_down
[WARNING] [MTD ] Unable to open device "/dev/input/event11". Please ensure you have the appropriate permissions.
if child.dispatch('on_touch_down', touch):
File "kivy/_event.pyx", line 731, in kivy._event.EventDispatcher.dispatch
File "/home/administrator/Documents/app/env/lib/python3.8/site-packages/kivymd/uix/behaviors/ripple_behavior.py", line 259, in on_touch_down
super().on_touch_down(touch)
File "/home/administrator/Documents/app/env/lib/python3.8/site-packages/kivy/uix/behaviors/button.py", line 150, in on_touch_down
self._do_press()
File "/home/administrator/Documents/app/env/lib/python3.8/site-packages/kivy/uix/behaviors/togglebutton.py", line 118, in _do_press
self.state = 'normal' if self.state == 'down' else 'down'
File "kivy/properties.pyx", line 520, in kivy.properties.Property.__set__
File "kivy/properties.pyx", line 567, in kivy.properties.Property.set
File "kivy/properties.pyx", line 606, in kivy.properties.Property._dispatch
File "kivy/_event.pyx", line 1307, in kivy._event.EventObservers.dispatch
File "kivy/_event.pyx", line 1213, in kivy._event.EventObservers._dispatch
File "/home/administrator/Documents/app/env/lib/python3.8/site-packages/kivymd/uix/selectioncontrol/selectioncontrol.py", line 328, in on_state
self.active = True
File "kivy/properties.pyx", line 520, in kivy.properties.Property.__set__
File "kivy/properties.pyx", line 567, in kivy.properties.Property.set
File "kivy/properties.pyx", line 606, in kivy.properties.Property._dispatch
File "kivy/_event.pyx", line 1307, in kivy._event.EventObservers.dispatch
File "kivy/_event.pyx", line 1213, in kivy._event.EventObservers._dispatch
File "/home/administrator/Documents/app/env/lib/python3.8/site-packages/kivymd/uix/datatables/datatables.py", line 1625, in notify_checkbox_click
self.table.get_select_row(self.index)
File "/home/administrator/Documents/app/env/lib/python3.8/site-packages/kivymd/uix/datatables/datatables.py", line 500, in get_select_row
self._parent.dispatch("on_check_press", row)
File "kivy/_event.pyx", line 727, in kivy._event.EventDispatcher.dispatch
File "kivy/_event.pyx", line 1307, in kivy._event.EventObservers.dispatch
File "kivy/_event.pyx", line 1231, in kivy._event.EventObservers._dispatch
File "./test.py", line 99, in on_check_press
self.data_tables.remove_row(tuple(current_row))
File "/home/administrator/Documents/app/env/lib/python3.8/site-packages/kivymd/uix/datatables/datatables.py", line 1502, in remove_row
self.row_data.remove(data)
File "kivy/properties.pyx", line 853, in kivy.properties.ObservableList.remove
ValueError: list.remove(x): x not in list
line 99, in on_check_press self.data_tables.remove_row(tuple(current_row)) File "/home/administrator/Documents/app/env/lib/python3.8/site-packages/kivymd/uix/datatables/datatables.py", line 1502, in remove_row self.row_data.remove(data) File "kivy/properties.pyx", line 853, in kivy.properties.ObservableList.remove ValueError: list.remove(x): x not in list
@Jeremy-SohOvercomplicated Why didn't you provide an algorithm of actions in the description of the issue to reproduce the error?
Didn't think it was necessary. The only change made to your provided example were already listed in description. Sorry. Hopefully the additional information helps reproduce the issue.
I am experiencing the same issue. KivyMD version is latest cloned from github master branch Steps to reproduce
- Run the code provided by @Jeremy-EpicHomeTech (or) a simpler one taken from kivymd docs and slightly modified to add icons to the row data
from kivy.metrics import dp
from kivy.lang import Builder
from kivy.clock import Clock
from kivymd.app import MDApp
from kivymd.uix.datatables import MDDataTable
from kivymd.uix.screen import MDScreen
KV = """
MDBoxLayout:
orientation: "vertical"
padding: "56dp"
spacing: "24dp"
MDData:
id: table_screen
MDRaisedButton:
text: "DELETE CHECKED ROWS"
on_release: table_screen.delete_checked_rows()
"""
class MDData(MDScreen):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.data = [
[
"1",
"Asep Sudrajat",
(
"human-male",
"Male",
),
"Soccer",
],
[
"2",
"Egy",
(
"human-male",
"Male",
),
"Soccer",
],
[
"3",
"Tanos",
(
"human-female",
"Female",
),
"Soccer",
],
]
self.data_tables = MDDataTable(
use_pagination=True,
check=True,
column_data=[
("No", dp(30)),
("No Urut.", dp(30)),
("Alamat Pengirim", dp(30)),
("No Surat", dp(60)),
],
)
self.data_tables.row_data = self.data
self.add_widget(self.data_tables)
def delete_checked_rows(self):
def deselect_rows(*args):
self.data_tables.table_data.select_all("normal")
for data in self.data_tables.get_row_checks():
self.data_tables.remove_row(data)
Clock.schedule_once(deselect_rows)
class MyApp(MDApp):
def build(self):
self.theme_cls.theme_style = "Dark"
self.theme_cls.primary_palette = "Orange"
return Builder.load_string(KV)
MyApp().run()
On press of the delete button the row is to be deleted but instead an error is thrown that the element does not exist
Traceback (most recent call last):
File "z:\MR.DM\temp.py", line 86, in <module>
MyApp().run()
File "Z:\MR.DM\.venv\lib\site-packages\kivy\app.py", line 956, in run
runTouchApp()
File "Z:\MR.DM\.venv\lib\site-packages\kivy\base.py", line 574, in runTouchApp
EventLoop.mainloop()
File "Z:\MR.DM\.venv\lib\site-packages\kivy\base.py", line 339, in mainloop
self.idle()
File "Z:\MR.DM\.venv\lib\site-packages\kivy\base.py", line 383, in idle
self.dispatch_input()
File "Z:\MR.DM\.venv\lib\site-packages\kivy\base.py", line 334, in dispatch_input
post_dispatch_input(*pop(0))
File "Z:\MR.DM\.venv\lib\site-packages\kivy\base.py", line 302, in post_dispatch_input
wid.dispatch('on_touch_up', me)
File "kivy\_event.pyx", line 731, in kivy._event.EventDispatcher.dispatch
File "Z:\MR.DM\.venv\lib\site-packages\kivymd\uix\button\button.py", line 1145, in on_touch_up
return super().on_touch_up(touch)
File "Z:\MR.DM\.venv\lib\site-packages\kivymd\uix\behaviors\ripple_behavior.py", line 404, in on_touch_up
return super().on_touch_up(touch)
File "Z:\MR.DM\.venv\lib\site-packages\kivy\uix\behaviors\button.py", line 179, in on_touch_up
self.dispatch('on_release')
File "kivy\_event.pyx", line 727, in kivy._event.EventDispatcher.dispatch
File "kivy\_event.pyx", line 1307, in kivy._event.EventObservers.dispatch
File "kivy\_event.pyx", line 1191, in kivy._event.EventObservers._dispatch
File "Z:\MR.DM\.venv\lib\site-packages\kivy\lang\builder.py", line 55, in custom_callback
exec(__kvlang__.co_value, idmap)
File "<string>", line 12, in <module>
File "z:\MR.DM\temp.py", line 74, in delete_checked_rows
self.data_tables.remove_row(data)
File "Z:\MR.DM\.venv\lib\site-packages\kivymd\uix\datatables\datatables.py", line 1782, in remove_row
self.row_data.remove(data)
File "kivy\properties.pyx", line 853, in kivy.properties.ObservableList.remove
ValueError: list.remove(x): x not in list
On further inspection the function get_row_checks()
does not return icon nor color data.
What is returned: [['1', 'Asep Sudrajat', 'Male', 'Soccer']]
What should be returned [['1', 'Asep Sudrajat', ('human_male', 'Male'), 'Soccer']