Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python+kivy+SQLite: How to use them together

I am new to python, kivy and sqlite. But I have to do this difficult task. :-( Any kind of help will be highly appreciated. Thanks in advance!

The task is: to display the data from a .db file on the kivy screen on android.

I made the database file from http://zetcode.com/db/sqlitepythontutorial/

Here I post the code again.

#!/usr/bin/python
# -*- coding: utf-8 -*-

import sqlite3 as lite
import sys

con = lite.connect('test.db')

with con:

    cur = con.cursor()    
    cur.execute("CREATE TABLE Cars(Id INT, Name TEXT, Price INT)")
    cur.execute("INSERT INTO Cars VALUES(1,'Audi',52642)")
    cur.execute("INSERT INTO Cars VALUES(2,'Mercedes',57127)")
    cur.execute("INSERT INTO Cars VALUES(3,'Skoda',9000)")
    cur.execute("INSERT INTO Cars VALUES(4,'Volvo',29000)")
    cur.execute("INSERT INTO Cars VALUES(5,'Bentley',350000)")
    cur.execute("INSERT INTO Cars VALUES(6,'Citroen',21000)")
    cur.execute("INSERT INTO Cars VALUES(7,'Hummer',41400)")
    cur.execute("INSERT INTO Cars VALUES(8,'Volkswagen',21600)")

The database is then saved to C:\\test.db.

Then I made a kivy screen with a label and a button.

# -*- coding: utf-8 -*-

from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.label import Label
from kivy.lang import Builder

import random

root_widget = Builder.load_string('''
BoxLayout:
    orientation: 'vertical'
    Label:
        text: 'Hello'  #How to define it?
        font_size: 30
    Button:
        size: root.width/2, 15
        text: 'next random'
        font_size: 30
#        on_release:  #How to define it?
''')

class TestApp(App):
    def build(self):
        return root_widget

if __name__ == '__main__':
    TestApp().run()

I want to have a random car name from the db file shown on the label, when the button is clicked everytime.

The initial label text, which is now the word "Hello", should be replaced by a random car name. So that everytime the programm is run, a car name is shown on the label.

But I really dont know how to write the code.

Thank you for your help.

#Update

I wrote the code but it does not work.

# -*- coding: utf-8 -*-

from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.label import Label
from kivy.lang import Builder
from kivy.clock import mainthread
import sqlite3

import random


class MyBoxLayout(BoxLayout):

    def init(self, **kwargs):
        super().__init__(**kwargs)

        @mainthread  # execute within next frame
        def delayed():
            self.load_random_car()
        delayed()

    def load_random_car(self):
        conn = sqlite3.connect("C:\\test.db")
        cur = conn.cursor()

        ####Length of db file
        with conn:
            cur = conn.cursor()
            cur.execute("SELECT * FROM Cars")
            rows = cur.fetchall()
        LengthSQLFile = len(rows)
        print LengthSQLFile


        CurrentNo = random.randint(0, LengthSQLFile)
        CurrentNo_ForSearch = (CurrentNo ,)
        cur.execute("select * from Cars where rowid = ?" , CurrentNo_ForSearch)

        CurrentAll = cur.fetchone()
        CurrentAll = list(CurrentAll)   # Change it from tuple to list
        print CurrentAll

        Current    = CurrentAll[1]
        self.ids.label.text = Current #"fetch random car data from db and put here"


root_widget = Builder.load_string('''
BoxLayout:
    orientation: 'vertical'
    Label:
        id: label
        font_size: 30
    Button:
        size: root.width/2, 15
        text: 'next random'
        font_size: 30
        on_release:  root.load_random_car()

''')


class TestApp(App):
    def build(self):
#        MyBoxLayout(BoxLayout)
        return root_widget

if __name__ == '__main__':
    TestApp().run()

#2 Update:

The code now is... It shows the error message: AttributeError: 'BoxLayout' object has no attribute 'load_random_car'

# -*- coding: utf-8 -*-

from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.label import Label
from kivy.lang import Builder
from kivy.clock import mainthread
import sqlite3

import random

class MyBoxLayout(BoxLayout):

    def init(self, **kwargs):
        super().__init__(**kwargs)

        @mainthread  # execute within next frame
        def delayed():
            self.load_random_car()
        delayed()

    def load_random_car(self):
        conn = sqlite3.connect("C:\\test.db")
        cur = conn.cursor()

        cur.execute("SELECT * FROM Cars ORDER BY RANDOM() LIMIT 1;")

        currentAll = cur.fetchone()
        currentAll = list(currentAll)   # Change it from tuple to list
        print currentAll

        current    = currentAll[1]
        self.ids.label.text = current #"fetch random car data from db and put here"


root_widget = Builder.load_string('''
BoxLayout:
    orientation: 'vertical'
    Label:
        id: label
        font_size: 30
    Button:
        size: root.width/2, 15
        text: 'next random'
        font_size: 30
        on_release:  root.load_random_car()

''')


class TestApp(App):
    def build(self):
#        MyBoxLayout(BoxLayout)
        return root_widget

if __name__ == '__main__':
    TestApp().run()
like image 799
Rita Avatar asked Aug 14 '16 05:08

Rita


Video Answer


1 Answers

The easiest way would be writing a custom init method for the box layout:

from kivy.uix.boxlayout import BoxLayout
from kivy.clock import mainthread

class MyBoxLayout(BoxLayout):

    def init(self, **kwargs):
        super().__init__(**kwargs)

        @mainthread  # execute within next frame
        def delayed():
            self.load_random_car()
        delayed()

    def load_random_car(self):
        self.ids.label.text = "fetch random car data from db and put here"

This is how the updated widget structure would look like:

MyBoxLayout:
    Label:
        id: label
    Button:
        on_release:  root.load_random_car()
like image 100
jligeza Avatar answered Oct 21 '22 08:10

jligeza