Python+kivy+SQLite:如何一起使用 [英] Python+kivy+SQLite: How to use them together

查看:7

问题描述

我是 python、kivy 和 sqlite 的新手.但我必须完成这项艰巨的任务.:-( 任何形式的帮助将不胜感激.在此先感谢!

任务是:在 android 的 kivy 屏幕上显示 .db 文件中的数据.

我从 http://zetcode.com/db/sqlitepythontutorial/ 制作了数据库文件/p>

在这里我再次发布代码.

#!/usr/bin/python# -*- 编码:utf-8 -*-将 sqlite3 导入为 lite导入系统con = lite.connect('test.db')与骗局: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,'沃尔沃',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)")

然后将数据库保存到 C:\test.db.

然后我制作了一个带有 label 和一个 buttonkivy 屏幕.

# -*- 编码:utf-8 -*-从 kivy.app 导入应用程序从 kivy.uix.boxlayout 导入 BoxLayout从 kivy.uix.label 导入标签从 kivy.lang 导入生成器随机导入root_widget = Builder.load_string('''盒子布局:方向:垂直"标签:text: 'Hello' #如何定义?字体大小:30按钮:尺寸:root.width/2, 15文本:'下一个随机'字体大小:30# on_release: #如何定义?''')类测试应用程序(应用程序):定义构建(自我):返回 root_widget如果 __name__ == '__main__':TestApp().run()

我想要 label 上显示的 db 文件 中的 random car name,当button 每次都被点击.

最初的label文本,现在是Hello"这个词,应该被一个随机的车名代替.这样每次程序运行时,label 上都会显示一个汽车名称.

但我真的不知道如何编写代码.

感谢您的帮助.

#更新

我编写了代码,但它不起作用.

# -*- 编码:utf-8 -*-从 kivy.app 导入应用程序从 kivy.uix.boxlayout 导入 BoxLayout从 kivy.uix.label 导入标签从 kivy.lang 导入生成器从 kivy.clock 导入主线程导入 sqlite3随机导入类 MyBoxLayout(BoxLayout):def init(self, **kwargs):super().__init__(**kwargs)@mainthread # 在下一帧内执行默认延迟():self.load_random_car()延迟()def load_random_car(self):conn = sqlite3.connect("C:\test.db")cur = conn.cursor()####db文件长度与连接:cur = conn.cursor()cur.execute("SELECT * FROM Cars")行 = cur.fetchall()LengthSQLFile = len(行)打印 LengthSQLFileCurrentNo = random.randint(0, LengthSQLFile)CurrentNo_ForSearch = (CurrentNo ,)cur.execute("select * from Cars where rowid = ?" , CurrentNo_ForSearch)CurrentAll = cur.fetchone()CurrentAll = list(CurrentAll) # 将元组改为列表打印当前全部当前 = CurrentAll[1]self.ids.label.text = Current #"从数据库中获取随机汽车数据并放在这里"root_widget = Builder.load_string('''盒子布局:方向:垂直"标签:编号:标签字体大小:30按钮:尺寸:root.width/2, 15文本:'下一个随机'字体大小:30on_release: root.load_random_car()''')类测试应用程序(应用程序):定义构建(自我):#MyBoxLayout(BoxLayout)返回 root_widget如果 __name__ == '__main__':TestApp().run()

#2 更新:

现在的代码是...它显示错误消息:AttributeError: 'BoxLayout' object has no attribute 'load_random_car'

# -*- 编码:utf-8 -*-从 kivy.app 导入应用程序从 kivy.uix.boxlayout 导入 BoxLayout从 kivy.uix.label 导入标签从 kivy.lang 导入生成器从 kivy.clock 导入主线程导入 sqlite3随机导入类 MyBoxLayout(BoxLayout):def init(self, **kwargs):super().__init__(**kwargs)@mainthread # 在下一帧内执行默认延迟():self.load_random_car()延迟()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) # 将元组改为列表打印当前全部当前 = currentAll[1]self.ids.label.text = current #"从数据库中获取随机汽车数据并放在这里"root_widget = Builder.load_string('''盒子布局:方向:垂直"标签:编号:标签字体大小:30按钮:尺寸:root.width/2, 15文本:'下一个随机'字体大小:30on_release: root.load_random_car()''')类测试应用程序(应用程序):定义构建(自我):#MyBoxLayout(BoxLayout)返回 root_widget如果 __name__ == '__main__':TestApp().run()

解决方案

最简单的方法是为盒子布局编写一个自定义的 init 方法:

从 kivy.uix.boxlayout 导入 BoxLayout从 kivy.clock 导入主线程类 MyBoxLayout(BoxLayout):def init(self, **kwargs):super().__init__(**kwargs)@mainthread # 在下一帧内执行默认延迟():self.load_random_car()延迟()def load_random_car(self):self.ids.label.text = "从数据库中获取随机汽车数据并放在这里"

这是更新后的小部件结构的样子:

MyBoxLayout:标签:编号:标签按钮:on_release: root.load_random_car()

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()

解决方案

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()

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆