Python+kivy+SQLite:如何一起使用
Posted
技术标签:
【中文标题】Python+kivy+SQLite:如何一起使用【英文标题】:Python+kivy+SQLite: How to use them together 【发布时间】:2016-12-20 17:37:09 【问题描述】:我是 python、kivy 和 sqlite 的新手。但我必须完成这项艰巨的任务。 :-( 任何形式的帮助将不胜感激。在此先感谢!
任务是:在android的kivy
屏幕上显示来自.db
文件的数据。
我从http://zetcode.com/db/sqlitepythontutorial/创建了数据库文件
在这里我再次发布代码。
#!/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)")
然后将数据库保存到C:\\test.db
。
然后我用label
和button
制作了一个kivy
屏幕。
# -*- 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()
我想要label
上显示的db file
中的random
汽车名称,每次都点击button
。
最初的label
文本,现在是“Hello”这个词,应该被一个随机的车名替换。因此,每次运行程序时,label
上都会显示汽车名称。
但我真的不知道如何编写代码。
感谢您的帮助。
#更新
我编写了代码,但它不起作用。
# -*- 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 更新:
现在的代码是...它显示错误消息: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()
【问题讨论】:
什么不起作用?为什么要查询搜索两次?使用第一个查询获取数据后,只需选择带有random.choice(rows)
的随机条目。另外,请不要以大写字母开头的变量名——它们是为类名保留的。
@jligeza 感谢您的提示。我改变了它。但它仍然显示错误消息:'BoxLayout' object has no attribute 'load_random_car'
@jligeza 我粘贴了更新。请你看一下好吗?谢谢。
在kv字符串部分,你应该使用MyBoxLayout
,而不是普通的BoxLayout
。
@jligeza 就是这样!谢谢!
【参考方案1】:
最简单的方法是为盒子布局编写自定义 init
方法:
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"
这是更新后的小部件结构的样子:
MyBoxLayout:
Label:
id: label
Button:
on_release: root.load_random_car()
【讨论】:
非常感谢!但是我仍然对您的代码有疑问。能否请您为我编写一个框架代码,告诉我如何加载 db 文件,如何获取 db 数据等等?那对我会有很大的帮助。谢谢。 @Rita 加载 db 文件并从中获取数据在您链接的教程中写得很清楚。教程的哪一部分你不明白? 谢谢。我实际上是在寻找“类”语句来加载和读取 db 文件。但我在网上找不到这样的说法。 @Rita 如果你想用类来描述一个 sql 数据库结构,那么我强烈推荐你peewee。它超级简单高效。还有更简单的数据存储形式(没有 sql,没有类,我的最爱之一)tinydb。 @Rita 我一直在 kivy 项目中在 android 上使用 peewee。 QPython 默认没有安装它。最简单的方法是使用buildozer 在需求中导入它。另外,如果足够,请考虑将此答案标记为已接受。以上是关于Python+kivy+SQLite:如何一起使用的主要内容,如果未能解决你的问题,请参考以下文章
Kivy 1.8.x Python3 对 Ubuntu 的支持