Display Table from Database

461 views
Skip to first unread message

kivy

unread,
Jan 18, 2021, 2:33:35 AM1/18/21
to Kivy users support
I want to display table on screen from database. My code is here:

main.py:
class MyScreen(Screen):
   data_items = ListProperty([])

    def __init__(self, **kwargs):
       super(MyScreen, self).__init__(**kwargs)
       self.get_data()
   
   def get_data(self):
       connection = sqlite3.connect('test.db')
       cursor = connection.cursor()
       cursor.execute("SELECT * FROM table ORDER BY pos ASC")
       rows = cursor.fetchall()
       for row in rows:
           for col in row:
               self.data_items.append(col)

kv:
<MyScreen>:
   BoxLayout:
       orientation: "vertical"

        GridLayout:
           size_hint: 1, None
           size_hint_y: None
           height: 25
           cols: 6

            Label:
               text: "Pos"
           Label:
               text: "Name"
           Label:
               text: "A"
           Label:
               text: "B"
           Label:
               text: "C"
           Label:
               text: "Num"

        BoxLayout:
           data: [{'text': str(x)} for x in root.data_items]
           cols: 6
           default_size: None, dp(26)
           default_size_hint: 1, None
           size_hint_y: None
           height: self.minimum_height
           orientation: 'vertical'
           multiselect: True
           touch_multiselect: True

It's don't display any data on screen.

ElliotG

unread,
Jan 18, 2021, 8:40:45 AM1/18/21
to Kivy users support
It looks like you are trying to use a RecycleView, Is that right?   You have created a list of dictionaries and assigned it to data.  The data attribute is an attribute of RecycleView.  You will need to create a viewclass, and a Recycleview.

Here is an example using a RecycleView and multiple data items in the viewclass.  You will create a viewclass with a separate label for each of the columns in your database.

from kivy.app import App
from kivy.lang import Builder
from kivy.uix.boxlayout import BoxLayout
from kivy.properties import NumericProperty, StringProperty, ListProperty

kv = """
<TestBox>
    padding: 2
    Button:
        size_hint_x: None
        width: 100
        text: str(root.button_value)
        on_release: 
            print(f'Button: {root.text} pressed, with button value {root.button_value} idx: {root.idx}')
            app.root.color_list[root.idx] = (0, 0, 0)
    Label:
        text: root.text
        canvas.before:
            Color:
                rgb: app.root.color_list[root.idx]
            Rectangle:
                pos: self.pos
                size: self.size
    
RootBox:
    orientation: 'vertical'
    BoxLayout:
        size_hint_y: None
        height: 48
        Button:
            text: 'print info'
            on_release: root.print_info()
        Button:
            text: 'Color Even Green'
            on_release: root.color_even((0, .7, 0))
        Button:
            text: 'Color Even Red'
            on_release: root.color_even((.7, 0, 0))
        Button:
            text: 'Add 20 items'
            on_release: root.append_20()
            
    RecycleView:
        id: rv
        viewclass: 'TestBox'
        data: root.rv_data_list
        scroll_type: ['bars','content']
        bar_width: dp(20)
        do_scroll_x: False
        RecycleGridLayout:
            cols: 3
            default_size: None, dp(56)
            default_size_hint: 1, None
            size_hint_y: None
            height: self.minimum_height
   
"""


class TestBox(BoxLayout):
    button_value = NumericProperty()
    text = StringProperty()
    idx = NumericProperty()

class RootBox(BoxLayout):
    rv_data_list = ListProperty([{'text': 'Label ' + str(n),
                     'idx' : n,
                     'button_value': n} for n in range(20)])
    color_list = ListProperty([(0,.5, .7)] * 20)

    def print_info(self):
        print(f'viewclass: {self.ids.rv.viewclass}')
        print(f'data: {self.rv_data_list}')
        print(f'self.ids.rv.view_adapter.views: {self.ids.rv.view_adapter.views}')

    def color_even(self, color):
        end = len(self.color_list)
        for i in range(0, end, 2):
            self.color_list[i] = color

    def append_20(self):
        end = len(self.rv_data_list)
        new_items = [{'text': 'Label ' + str(n),
                     'idx' : n,
                     'button_value': n} for n in range(end, end + 20)]
        new_colors = [(0,.5, .7) for _ in range(end, end + 20)]
        self.rv_data_list.extend(new_items)
        self.color_list.extend(new_colors)


class RVTestApp(App):
    def build(self):
        return Builder.load_string(kv)


RVTestApp().run()

kivy

unread,
Jan 18, 2021, 10:31:08 AM1/18/21
to Kivy users support
I just want create table and fill labels from database. Doesn't matter RecycleView or something. I want make this table only in one class. Could you configure my sample code?

18 Ocak 2021 Pazartesi 16:40:45 UTC+3 tarihinde ElliotG yazdı:

Elliot Garbus

unread,
Jan 18, 2021, 4:05:47 PM1/18/21
to kivy-...@googlegroups.com

Start by creating a minimal runnable example.

If you have a small number of items that can fit in a Window, use a Grid or BoxLayout

If you have up to say 100 line items use a ScrollView.

If you have more or plan on primarily  running on mobile, use a RecycleView.

 

Give it a try. 

--
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/6f65c760-f4ce-43c5-97a5-7f2bb7db0314o%40googlegroups.com.

 

kivy

unread,
Jan 18, 2021, 4:12:49 PM1/18/21
to Kivy users support
I have usually 20-30 lines data at the database. I have to fetch 6 columns and 20 rows data. I can create static table at the kv but I can't make it dynamically with sql query.

19 Ocak 2021 Salı 00:05:47 UTC+3 tarihinde ElliotG yazdı:

To unsubscribe from this group and stop receiving emails from it, send an email to kivy-...@googlegroups.com.

Elliot Garbus

unread,
Jan 18, 2021, 4:34:25 PM1/18/21
to kivy-...@googlegroups.com

Create a class that holds one row of data.

For each row of data, instance the class and initialize with the data.

Add the class to the widget tree under a scrollview.

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/6bdd07ea-42e9-4eb7-b904-7b184073c4b1o%40googlegroups.com.

 

kivy

unread,
Jan 19, 2021, 7:41:40 AM1/19/21
to Kivy users support
Can you give me example of code please?

19 Ocak 2021 Salı 00:34:25 UTC+3 tarihinde ElliotG yazdı:

Elliot Garbus

unread,
Jan 19, 2021, 11:05:03 AM1/19/21
to kivy-...@googlegroups.com

Here is an example.

 
 
 
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.boxlayout import BoxLayout
from kivy.properties import StringProperty

kv =
"""
<DataLine>:  # class to hold one line of data
    canvas:
        Color:
            rgb: .3, .3, .3
        Line:
            width: 2
            rectangle: (*self.pos, *self.size)
    size_hint_y: None
    height: 48
    Label:
        text: root.name
    Label:
        text: root.color
    Label:
        text: root.birthday

BoxLayout:
    orientation: 'vertical'
    Label:
        size_hint_y: None
        height: 48
        text: 'Data List in a Scrollview Example'
    BoxLayout:  # Headings for
        size_hint_y: None
        height: 48
        Label:
            text: 'Name'
        Label:
            text: 'Favorite Color'
        Label:
            text: 'Birthday'
    ScrollView:
        do_scroll_y: True
        bar_width: dp(10)
        scroll_type: ['bars','content']
        BoxLayout:
            orientation: 'vertical'
            id:scroll_box
            size_hint_y: None
            height: self.minimum_height
"""


class DataLine(BoxLayout):  # class to hold one line of data
   
name = StringProperty()
    color = StringProperty()
    birthday = StringProperty()


class DataApp(App):
   
def build(self):
       
return Builder.load_string(kv)

   
def on_start(self):
        info = [[
'Michael', 'Blue',     '1/30/2020'],  # simulating what could come out of a database
               
['Carol',   'Green',    '12/3/2020'],
                [
'Bill',    'Red',      '3/12/2020'],
                [
'Sue',     'Orange',   '7/4/2020'],
                [
'John',    'Blue',     '5/23/2020'],
                [
'Jane',    'Yellow',   '3/9/2020'],
                [
'Michael', 'Blue',     '2/30/2020'],
                [
'Carol',   'Green',    '4/3/2020'],
                [
'Bill',    'Red',      '3/12/2020'],
                [
'Sue',     'Orange',   '8/4/2020'],
                [
'John',    'Blue',     '10/23/2020'],
                [
'Jane',    'Yellow',   '6/9/2020']]

       
for line in info:
            name, color, bd = line
            w = DataLine(
name=name, color=color, birthday=bd)  # instancing the class
           
self.root.ids.scroll_box.add_widget(w)             # adding the class to the scrollview


DataApp().run()

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/fa224291-abf8-4cfc-aa0b-61e9403bda69o%40googlegroups.com.

 

kivy

unread,
Jan 19, 2021, 2:16:43 PM1/19/21
to Kivy users support
I configured this code for me but I'm getting error. Here is my code:

from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen
import sqlite3
from kivymd.app import MDApp
from kivy.properties import ListProperty, StringProperty
from kivy.uix.boxlayout import BoxLayout

kv = '''

BoxLayout:
   orientation: 'vertical'
   MDToolbar:
       id: toolbar
       elevation: 10
       title: "Sports App"
       left_action_items: [["menu", lambda x: nav_drawer.set_state("open")]]

    MDNavigationLayout:
       ScreenManager:
           id: screen_manager
           HomeScreen:
               id: home
               name: 'home'
           FBScreen:
               id: fb
               name: 'fb'
               
       MDNavigationDrawer:
           id: nav_drawer
           ScrollView:
               MDList:
                   OneLineListItem:
                       icon: 'soccer'
                       text: "Home"
                       on_press:
                           nav_drawer.set_state("close")
                           screen_manager.current = "home"
                   OneLineListItem:
                       text: "Football"
                       on_press:
                           nav_drawer.set_state("close")
                           screen_manager.current = "fb"

<HomeScreen>:
   MDLabel:
       text: 'Home screen'
       halign: 'center'

<FBData>:
   canvas:
       Color:
           rgb: .3, .3, .3
       Line:
           width: 2
           rectangle: (*self.pos, *self.size)
   size_hint_y: None
   height: 48
   Label:
       text: root.fbPos
   Label:
       text: root.fbName
   Label:
       text: root.fbW
   Label:
       text: root.fbL
   Label:
       text: root.fbD
   Label:
       text: root.fbP

<FBScreen>:
   BoxLayout:
       orientation: 'vertical'
       Label:
           size_hint_y: None
           height: 48
           text: 'Data List in a Scrollview Example'
       BoxLayout:  # Headings for
            size_hint_y: None
           height: 48
           Label:
               text: 'Pos'
           Label:
               text: 'Name'
           Label:
               text: 'W'
           Label:
               text: 'L'
           Label:
               text: 'D'
           Label:
               text: 'Point'
       ScrollView:
           do_scroll_y: True
           bar_width: dp(10)
           scroll_type: ['bars','content']
           BoxLayout:
               orientation: 'vertical'
               id:scroll_box
               size_hint_y: None
               height: self.minimum_height



'''


class FBData(BoxLayout):
   fbName = StringProperty()
   fbPos = StringProperty()
   fbW = StringProperty()
   fbL = StringProperty()
   fbD = StringProperty()
   fbP = StringProperty()

class FBScreen(Screen):
   def on_start(self):
       con = sqlite3.connect('test.db')
       cur = con.cursor()
       cur.execute("SELECT * FROM soccer ORDER BY pos ASC")
       table = cur.fetchall()

        for line in table:
           pos, name, win, lose, draw, point = line
           w = FBData(fbPos = str(pos), fbName = name, fbW = str(win), fbL = str(lose), fbD = str(draw), fbP = str(point))
           self.ids.scroll_box.add_widget(w)


    def __init__(self, **kwargs):
       super(FBScreen, self).__init__(**kwargs)
       self.on_start()
   
class ScrManage(ScreenManager):
   pass

class Sports(MDApp):
   def build(self):
       return Builder.load_string(kv)


Sports().run()


Error code: 

 AttributeError: 'super' object has no attribute '__getattr__'



19 Ocak 2021 Salı 19:05:03 UTC+3 tarihinde ElliotG yazdı:

Elliot Garbus

unread,
Jan 19, 2021, 2:46:20 PM1/19/21
to kivy-...@googlegroups.com

You do not want to use ids in the __init__() the kv code has not been processed yet.  Instead you can use on_kv_post()

See: https://kivy.org/doc/stable/api-kivy.uix.widget.html?highlight=widget#kivy.uix.widget.Widget

 

class FBScreen(Screen):
   
def on_kv_post(self, base_widget):
        con = sqlite3.connect(
'test.db')
        cur = con.cursor()
        cur.execute(
"SELECT * FROM soccer ORDER BY pos ASC")
        table = cur.fetchall()

       
for line in table:

            pos, name, win, lose, draw, point = line
            w = FBData(
fbPos=str(pos), fbName=name, fbW=str(win), fbL=str(lose), fbD=str(draw), fbP=str(point))
           
self.ids.scroll_box.add_widget(w)


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/4c6cf190-32e3-469b-833a-6c7ed2729c80o%40googlegroups.com.

 

kivy

unread,
Jan 19, 2021, 3:10:45 PM1/19/21
to Kivy users support
Thank you so much! It works!

19 Ocak 2021 Salı 22:46:20 UTC+3 tarihinde ElliotG yazdı:

Elliot Garbus

unread,
Jan 19, 2021, 3:19:43 PM1/19/21
to kivy-...@googlegroups.com

😊

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/1fde09f1-57cf-4969-b885-f640f8ffe678o%40googlegroups.com.

 

Reply all
Reply to author
Forward
0 new messages