Dynamically adding a row in data table Kivy/KivyMD
Question:
For example I have an empty data table (with only column data) and a button. I want to dynamically add row data when button is pressed. Is it even possible?
Answers:
Yes and no. The widget MDDataTable
doesn’t permit natively the addition of data dynamically to the table, as is discussed here.
Nonetheless, one can easily circumvent that by creating a new the table with the new data and show it. It can become process heavy, but for smaller tables it works just fine.
I made an example using kivy 2.0.0 and kivymd 0.104.1:
from kivy.metrics import dp
from kivy.uix.button import Button
from kivymd.app import MDApp
from kivymd.uix.datatables import MDDataTable
class Example(MDApp):
def build(self):
self.i = 0
self.rowData = ["Row. No."]
self.button = Button(text="AddRow", size_hint_y=None, pos_hint={"bottom": 0})
self.button.bind(texture_size=self.button.setter('size'))
self.data_tables = None
self.set_table(self.rowData)
def set_table(self, data):
if self.data_tables:
self.data_tables.ids.container.remove_widget(self.button)
self.data_tables = MDDataTable(size_hint=(0.9, 0.6), use_pagination=True, check=True,
column_data=[("No.", dp(30))], row_data=[self.rowData])
self.data_tables.ids.container.add_widget(self.button)
def on_start(self):
self.data_tables.open()
self.button.bind(on_press=lambda x: self.addrow())
def addrow(self):
self.data_tables.dismiss(animation=False)
self.i += 1
self.set_table(self.rowData.append("Row {}".format(self.i)))
self.data_tables.open(animation=False)
if __name__ == '__main__':
Example().run()
Note: While running this code i ran into an error:
ValueError: TableRecycleGridLayout.orientation is set to an invalid option 'vertical'. Must be one of: ['lr-tb', 'tb-lr', 'rl-tb', 'tb-rl', 'lr-bt', 'bt-lr', 'rl-bt', 'bt-rl']
It’s a known issue of incompatibility. To solve it, all there is needed is to follow the instructions in this here
AttributeError: ‘MDDataTable’ object has no attribute ‘open’
Yes, we can dynamically add rows, just add a row to the row_data array.
To dynamically update the item index, simply find out the length of the array len(self.data_table.row_data), and this will be our last item and simply add +1
def add_row(self):
self.data_table.row_data.append([str(len(self.data_table.row_data)+1),
"2","3","4"])
For example I have an empty data table (with only column data) and a button. I want to dynamically add row data when button is pressed. Is it even possible?
Yes and no. The widget MDDataTable
doesn’t permit natively the addition of data dynamically to the table, as is discussed here.
Nonetheless, one can easily circumvent that by creating a new the table with the new data and show it. It can become process heavy, but for smaller tables it works just fine.
I made an example using kivy 2.0.0 and kivymd 0.104.1:
from kivy.metrics import dp
from kivy.uix.button import Button
from kivymd.app import MDApp
from kivymd.uix.datatables import MDDataTable
class Example(MDApp):
def build(self):
self.i = 0
self.rowData = ["Row. No."]
self.button = Button(text="AddRow", size_hint_y=None, pos_hint={"bottom": 0})
self.button.bind(texture_size=self.button.setter('size'))
self.data_tables = None
self.set_table(self.rowData)
def set_table(self, data):
if self.data_tables:
self.data_tables.ids.container.remove_widget(self.button)
self.data_tables = MDDataTable(size_hint=(0.9, 0.6), use_pagination=True, check=True,
column_data=[("No.", dp(30))], row_data=[self.rowData])
self.data_tables.ids.container.add_widget(self.button)
def on_start(self):
self.data_tables.open()
self.button.bind(on_press=lambda x: self.addrow())
def addrow(self):
self.data_tables.dismiss(animation=False)
self.i += 1
self.set_table(self.rowData.append("Row {}".format(self.i)))
self.data_tables.open(animation=False)
if __name__ == '__main__':
Example().run()
Note: While running this code i ran into an error:
ValueError: TableRecycleGridLayout.orientation is set to an invalid option 'vertical'. Must be one of: ['lr-tb', 'tb-lr', 'rl-tb', 'tb-rl', 'lr-bt', 'bt-lr', 'rl-bt', 'bt-rl']
It’s a known issue of incompatibility. To solve it, all there is needed is to follow the instructions in this here
AttributeError: ‘MDDataTable’ object has no attribute ‘open’
Yes, we can dynamically add rows, just add a row to the row_data array.
To dynamically update the item index, simply find out the length of the array len(self.data_table.row_data), and this will be our last item and simply add +1
def add_row(self):
self.data_table.row_data.append([str(len(self.data_table.row_data)+1),
"2","3","4"])