How to use KivyMD and display data from a table and allow a person to delete a row using .kv file

1,503 views
Skip to first unread message

rocki...@gmail.com

unread,
Aug 7, 2021, 3:01:34 PM8/7/21
to Abridged Recipients
Hi all 

I have a navbar and screens application I am working on.  I want to have a screen called manage data.  When they click on that item in the navbar list, it takes them to a screen showing the data of a table from the database. 

The datatable will show the id column.

Then at the bottom of the screen is a box that says, enter id number to delete

they enter the number and then click the delete button to delete this row from the database table.

I know how to do the id text box and the delete button... 

what I can't seem to figure out is how to make the screen populate with the values from the database table.


Thanks in advance for your assistance
Dean-O

Elliot Garbus

unread,
Aug 7, 2021, 3:32:40 PM8/7/21
to kivy-...@googlegroups.com

How are you displaying you database table?

If you are using a kivymd data table, you would populate the column data and row data lists, pulling the data from your database.

After you update the row data, you would call update_row_data()

 

If you are using a RecycleView, the data is displayed as a list of dicts.  You will pull the data from the db, and create the list of dicts.  You would delete a row from the list of dicts, and the Recycle view will update when the property changes.

--
You received this message because you are subscribed to the Google Groups "Kivy users support" group.
To unsubscribe from this group and stop receiving emails from it, send an email to kivy-users+...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/kivy-users/268887625.199389.1628362884425%40mail.yahoo.com.

 

Dean-O Rochester

unread,
Aug 7, 2021, 4:40:01 PM8/7/21
to Kivy users support
Hi Elliot

As of now I am not displaying any data... I am not sure how to do that.  I have looked through many online areas but not seeing how this works from a navbar popping up a screen and having it already populated with the datatable of data.  

lots of simple examples of one screen app that has data in it when the app opens.  

Maybe that is what I need to do, but it didn't look like the solution.

Thanks
Dean-O

Elliot Garbus

unread,
Aug 7, 2021, 5:04:51 PM8/7/21
to kivy-...@googlegroups.com

I’m not sure where you have having a problem.

I assume you are using a NavigationDrawer (is that correct?)

If so NavigationDrawer works with a screen manager and screens.  Each screen has an even, on_pre_enter(), this event is fired when the screen is selected prior to the transition animation.  You could use this event to populate you datatable.  This would be appropriate if your data is changing frequently.  If your data is not changing every time the screen is opened you could populate the data initially in App.on_start().

 

If you have some code, I’ll take a look.

Dean-O Rochester

unread,
Aug 7, 2021, 7:02:27 PM8/7/21
to kivy-...@googlegroups.com
Hi Elliot 
Yes I am using a Navigation Drawer and screens. 

Each time the screen is opened I want to query what is in the table and show it on the screen. 

Id Hour Day Month 

Are the columns. 

Then a text box with a label saying enter the if to delete 

And a submit button. 

It’s the populating the little table I am stuck on 

Dean-O

Sent from my Droid-iPodPad-Berry

On Aug 7, 2021, at 5:04 PM, Elliot Garbus <elli...@cox.net> wrote:


You received this message because you are subscribed to a topic in the Google Groups "Kivy users support" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/kivy-users/okBErmrebu4/unsubscribe.
To unsubscribe from this group and all its topics, send an email to kivy-users+...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/kivy-users/610ef56d.1c69fb81.c353b.6a31SMTPIN_ADDED_MISSING%40gmr-mx.google.com.

Dean-O Rochester

unread,
Aug 7, 2021, 7:29:46 PM8/7/21
to Kivy users support
Hi all

Here is my app so far

from kivy.lang import Builder
from kivy.uix.boxlayout import BoxLayout
from kivy.properties import ObjectProperty

from kivy.uix.stacklayout import StackLayout

from kivy.uix.scrollview import ScrollView

from kivymd.uix.dialog import MDDialog

from kivymd.app import MDApp

import webbrowser

import sqlite3 as sql

KV = '''
#:import ScrollEffect  kivy.effects.scroll.ScrollEffect
<ContentNavigationDrawer>:

    ScrollView:

        MDList:

            OneLineListItem:
                text: "Welcome"
                on_press:
                    root.nav_drawer.set_state("close")
                    root.screen_manager.current = "welcome"

            OneLineListItem:
                text: "Manage Data"
                on_press:
                    root.nav_drawer.set_state("close")
                    root.screen_manager.current = "managedata"




MDBoxLayout:  #changed from Screen.  Screen is a relative layout
    orientation: 'vertical'

    MDToolbar:
        id: toolbar
        #pos_hint: {"top": 1}

        elevation: 10
        title: "Manage Database Data"
        left_action_items: [["menu", lambda x: nav_drawer.set_state("open")]]

    MDNavigationLayout:


        ScreenManager:
            id: screen_manager

            Screen:
                name: "welcome"

                MDBoxLayout:
                    orientation: "vertical"

                    ScrollView:
                        do_scroll_x: False
                        do_scroll_y: True
                        effect_cls: ScrollEffect

                        GridLayout:
                            size_hint_y: None
                            height: self.minimum_height
                            cols: 1
                            padding: "10dp"
                            spacing: "10dp"



                            MDLabel:
                                text: 'Welcome to the App.'
                                text_size: self.width, None
                                size_hint: 1, None
                                height: self.texture_size[1]

                            MDLabel:
                                text: 'Use the menu links to manage database data.'
                                text_size: self.width, None
                                size_hint: 1, None
                                height: self.texture_size[1]




            Screen:
                name: "managedata"
                id: managedata

                MDBoxLayout:
                    orientation: "vertical"

                    ScrollView:
                        do_scroll_x: False
                        do_scroll_y: True
                        effect_cls: ScrollEffect

                        GridLayout:
                            size_hint_y: None
                            height: self.minimum_height
                            cols: 1
                            padding: "10dp"
                            spacing: "10dp"

                            MDLabel:
                                text: 'Below is where a datatable would be of the rows from the database.  id  hour day month  are the columns'
                                text_size: self.width, None
                                size_hint: 1, None
                                height: self.texture_size[1]

                            MDTextField:
                                id: idtodelete
                                hint_text: "Enter Id To Delete"
                                helper_text: "id to delete"
                                helper_text_mode: "on_focus"

                            MDLabel:
                                id: statusmsg
                                text: ' '
                                text_size: self.width, None
                                size_hint: 1, None
                                height: self.texture_size[1]

                            MDRectangleFlatButton:
                                text: "Delete Id"
                                theme_text_color: "Custom"
                                text_color: 1, 0, 0, 1
                                line_color: 0, 0, 1, 1
                                size_hint: (None, None)
                                on_release: app.delete_by_id()



                            MDBoxLayout:
                                # this is a placeholder  The other objects are sized so this fills the remaining space




        MDNavigationDrawer:
            id: nav_drawer

            ContentNavigationDrawer:
                screen_manager: screen_manager
                nav_drawer: nav_drawer
'''


class ContentNavigationDrawer(BoxLayout):
    screen_manager = ObjectProperty()
    nav_drawer = ObjectProperty()


class TestNavigationDrawer(MDApp):
    def build(self):
        return Builder.load_string(KV)

    def delete_by_id(self):
        # make sql connection
        con = sql.connect('thedatabase.db')
        cur = con.cursor()
        tmpStr = f"delete from table1 where id = '{self.root.ids.idtodelete.text}')"
        # print(tmpStr)
        cur.execute(tmpStr)
        con.commit()
        con.close()
        tmpStr = f'Updated Info'
        self.root.ids.statusmsg.text = tmpStr


TestNavigationDrawer().run()


Dean-O Rochester

unread,
Aug 7, 2021, 9:00:13 PM8/7/21
to Kivy users support
I am getting closer... just not able to make the rows appear and move the other text down

Once I get static row data to appear.... I will have to figure out how to get the data from the database.


from kivy.lang import Builder
from kivy.uix.boxlayout import BoxLayout
from kivy.properties import ObjectProperty

from kivy.uix.stacklayout import StackLayout

from kivy.uix.scrollview import ScrollView

from kivymd.uix.dialog import MDDialog

from kivy.uix.anchorlayout import AnchorLayout

from kivymd.uix.datatables import MDDataTable
from kivy.metrics import dp
                on_pre_enter: app.load_data()

                MDBoxLayout:
                    orientation: "vertical"

                    ScrollView:
                        do_scroll_x: False
                        do_scroll_y: True
                        effect_cls: ScrollEffect

                        GridLayout:
                            size_hint_y: None
                            height: self.minimum_height
                            cols: 1
                            padding: "10dp"
                            spacing: "10dp"

                            MDLabel:
                                text: 'Below is where a datatable would be of the rows from the database.  id  hour day month  are the columns'
                                text_size: self.width, None
                                size_hint: 1, None
                                height: self.texture_size[1]



                            GridLayout:
                                size_hint_y: None
                                height: self.minimum_height
                                cols: 1
                                padding: "10dp"
                                spacing: "10dp"

                                AnchorLayout:
                                    id: data_layout
    def load_data(self):
        self.data_tables = MDDataTable(size_hint=(0.9, 0.8),
                                       column_data=[
                                           ("Not.", dp(30)),
                                           ("User", dp(30)),
                                           ("Password", dp(30)),
                                       ],
                                       row_data=[
                                           (
                                               "1",
                                               "The pitonist",
                                               "Strong password",
                                           ),
                                           (
                                               "2",
                                               "The c++ lover",
                                               "Save me!!!:)",
                                           ),
                                       ])
        self.root.ids.data_layout.add_widget(self.data_tables)

    def delete_by_id(self):
        # make sql connection
        con = sql.connect('thedatabase.db')
        cur = con.cursor()
        tmpStr = f"delete from table1 where id = '{self.root.ids.idtodelete.text}')"
        # print(tmpStr)
        cur.execute(tmpStr)
        con.commit()
        con.close()
        tmpStr = f'Updated Info'
        self.root.ids.statusmsg.text = tmpStr


TestNavigationDrawer().run()


Elliot Garbus

unread,
Aug 8, 2021, 1:09:35 PM8/8/21
to kivy-...@googlegroups.com

Here is an example of updating a datatable.   See the comments…

 

from kivy.metrics import dp
from kivy.lang import Builder
from kivy.properties import ListProperty
from kivymd.app import MDApp
from kivymd.uix.datatables import MDDataTable

from random import randint

kv =
"""
BoxLayout:
    orientation: 'vertical'
    Button:
        text:'Update Data'
        size_hint_y: None
        height: dp(48)
        on_release: app.update_data()

"""


class Example(MDApp):
    column_data = ListProperty()
    row_data = ListProperty()

   
def __init__(self, **kwargs):
       
super().__init__(**kwargs)
       
self.data_table = None  # holds the data table instance

   
def build(self):
       
return Builder.load_string(kv)

   
def on_start(self):
       
# pull data from your database, and set the list propertie
        # I am creating junk data here, you will pull the data from your db, and create tuples of the data to display
       
self.column_data = [ ("Column 1", dp(20)), ("Column 2", dp(30)), ("Column 3", dp(50))]
       
self.row_data = [(str(i), randint(10, 100), 'More Junk ' + str(randint(75, 150))) for i in range(10)]
       
self.data_table = MDDataTable(use_pagination=True, column_data=self.column_data, row_data=self.row_data)
       
self.root.add_widget(self.data_table)

   
def update_data(self):
       
# you would call this method with the on_pre_enter screen event
        # load you data from the database, replace or extend the row_data list
       
self.row_data = [(str(i), randint(10, 100), 'Updated Data ' + str(randint(75, 150))) for i in range(5)]
       
self.data_table.update_row_data(self.data_table, self.row_data)


Example().run()

Dean-O Rochester

unread,
Aug 8, 2021, 1:18:08 PM8/8/21
to Kivy users support
Hi Elliot

I see in the on start how you are adding a widget to the root...

but how, using my example of two screens, do you add that to the second screen like in my example?

Thanks
Dean-O

Elliot Garbus

unread,
Aug 8, 2021, 2:04:20 PM8/8/21
to kivy-...@googlegroups.com

There were a number of issues with the Layouts on the screen, such that you could not see the datatable.  I quickly commented out the code and made a few other minor layout changes to the screen.

It is not pretty – but you can see the datatable.

 

'''
                    id: data_layout

                    # ScrollView:
                    #     do_scroll_x: False
                    #     do_scroll_y: True
                    #     effect_cls: ScrollEffect
                    #
                    #     GridLayout:
                    #         size_hint_y: None
                    #         height: self.minimum_height
                    #         cols: 1
                    #         padding: "10dp"
                    #         spacing: "10dp"
                    #
                    #         MDLabel:
                    #             text: 'Below is where a datatable would be of the rows from the database.  id  hour day month  are the columns'
                    #             text_size: self.width, None
                    #             size_hint: 1, None
                    #             height: self.texture_size[1]


                            #
                            # GridLayout:
                            #     size_hint_y: None
                            #     height: self.minimum_height
                            #     cols: 1
                            #     padding: "10dp"
                            #     spacing: "10dp"

                    # AnchorLayout:
                    #     id: data_layout


                    MDBoxLayout:
                        size_hint_y: None
                        height: dp(48)

                        MDTextField:
                            id: idtodelete
                            hint_text: "Enter Id To Delete"
                            helper_text: "id to delete"
                            helper_text_mode: "on_focus"
   
                        MDLabel:
                            id: statusmsg
                            text: ' '
                            text_size: self.width, None
                            # size_hint: 1, None
                            # height: self.texture_size[1]

   
                        MDRectangleFlatButton:
                            text: "Delete Id"
                            theme_text_color: "Custom"
                            text_color: 1, 0, 0, 1
                            line_color: 0, 0, 1, 1
                            # size_hint: (None, None)
                            on_release: app.delete_by_id()
   
    
    
                        # MDBoxLayout:
                        #     # this is a placeholder  The other objects are sized so this fills the remaining space





        MDNavigationDrawer:
            id: nav_drawer

            ContentNavigationDrawer:
                screen_manager: screen_manager
                nav_drawer: nav_drawer
'''


class ContentNavigationDrawer(BoxLayout):
    screen_manager = ObjectProperty()
    nav_drawer = ObjectProperty()


class TestNavigationDrawer(MDApp):
   
def build(self):
       
return Builder.load_string(KV)

   
def load_data(self
):
       
self.data_tables = MDDataTable(size_hint=(1, 1),
                                      
column_data=[
                                           (
"Not.", dp(30)),
                                           (
"User", dp(30)),
                                           (
"Password", dp(30)),
                                       ],
                                      
row_data=[
                                           (
                                              
"1",
                                               
"The pitonist",
                                              
"Strong password",
                                           ),
                                           (
                                              
"2",
                                               
"The c++ lover",
                                              
"Save me!!!:)",
                                           ),
                                       ])
       
self.root.ids.data_layout.add_widget(self.data_tables)

   
def delete_by_id(self):
       
# make sql connection
       
con = sql.connect('thedatabase.db')
f"delete from table1 where id = '{self.root.ids.idtodelete.text}')"
       
# print(tmpStr)
       
cur.execute(tmpStr)
        con.commit()
        con.close()
        tmpStr =
f'Updated Info'
       
self.root.ids.statusmsg.text = tmpStr


TestNavigationDrawer().run()

Dean-O Rochester

unread,
Aug 8, 2021, 4:45:43 PM8/8/21
to Kivy users support
Hi Elliot

So close.  Now each time I click on the manage data page, it adds another MDDataTable  to the screen.  How do I get it to only show the updated table, not append a new table?

Thanks
Dean-O

Elliot Garbus

unread,
Aug 8, 2021, 5:03:13 PM8/8/21
to kivy-...@googlegroups.com

Look at the simple example I sent.

In the App class in on_start() read the database, set the column and row data lists, and then instance the MDDataTable.  In update_data(), you read you database and add or replace the data in the row data list.  Call update date from the on_pre_enter event.

 

Notice in update data, the data_table method update_row_data(), this is used to update the table with new data.

In my example I created new data, self.data_row is a list, you can append or extend to add the data from your database.

Dean-O Rochester

unread,
Aug 8, 2021, 7:28:36 PM8/8/21
to kivy-...@googlegroups.com
Thanks that did the trick 



Dean-O

Sent from my Droid-iPodPad-Berry

On Aug 8, 2021, at 5:03 PM, Elliot Garbus <elli...@cox.net> wrote:



Elliot Garbus

unread,
Aug 8, 2021, 8:38:58 PM8/8/21
to kivy-...@googlegroups.com

Glad you got it up and running!

Reply all
Reply to author
Forward
0 new messages