【发布时间】:2019-07-17 03:48:43
【问题描述】:
我的这部分代码基于此处其他帖子的文档和信息,例如:
How to fetch data from database and show in table in kivy+python
我们的目标是创建一个仅包含单词作为可选按钮的滚动单词列表,当您单击该按钮时,单词、发音和翻译应显示在弹出窗口中。所有这些都是从不断更新的 sqlite 数据库中的行中提取的。
我大部分时间都在工作,但我不知道该怎么做的一件事是分离数据,它采用字符串字典的形式,只显示列表中的单词(第 1 列)和所有弹出窗口中的信息(第 1、2 和 3 列)。我也不想遍历整个字典,因为虽然这里的示例数据库只有 8 个项目,但真正的有数千个。当我点击可选按钮时,我希望从数据库中提取信息。
是否可以从以下代码中的各个行中提取文本-
data: [{'text': f'{entry[0], entry[1], entry[2]}'} for entry in root.rows]
或将数据单独设置为变量并使用那些-
data: [{'text': f'{entry[0]}'} for entry in root.rows]
data2: [{'text': f'{entry[1]}'} for entry in root.rows]
data3: [{'text': f'{entry[2]}'} for entry in root.rows]
还有其他我想念的方法吗?
我遇到的另一个问题是可选按钮上的文本显示两次 - 在按钮上和下方(缩小窗口时可以看到),我不知道为什么或如何解决它.
感谢您的帮助。
数据库的最小代码:https://github.com/nitro9a/word_a_day_minimum
app.py:
import csv
import sqlite3
import random
import textwrap
from utils import database, scalelabel, scrollablelabel, recycleselect
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.label import Label
from kivy.uix.widget import Widget
from kivy.uix.button import Button
from kivy.uix.recycleview import RecycleView
from kivy.uix.relativelayout import RelativeLayout
from kivy.uix.recycleboxlayout import RecycleBoxLayout
from kivy.uix.recycleview.views import RecycleDataViewBehavior
from kivy.uix.recycleview.layout import LayoutSelectionBehavior
from kivy.uix.behaviors import FocusBehavior
from kivy.uix.popup import Popup
from kivy.uix.screenmanager import ScreenManager, Screen, NoTransition
from kivy.properties import BooleanProperty, ListProperty, ObjectProperty, StringProperty
word_dict = {}
class MessageBox(Popup):
def popup_dismiss(self):
self.dismiss()
obj = ObjectProperty(None)
obj_text = StringProperty('')
def __init__(self, obj, **kwargs):
super(MessageBox, self).__init__(**kwargs)
self.obj = obj
self.obj_text = obj.text #what is in the message box, will display same on click
class SelectableRecycleBoxLayout(FocusBehavior, LayoutSelectionBehavior, RecycleBoxLayout):
""" Adds selection and focus behaviour to the view. """
class SelectableButton(RecycleDataViewBehavior, Button):
""" Add selection support to the Label """
index = None
selected = BooleanProperty(False)
selectable = BooleanProperty(True)
def refresh_view_attrs(self, rv, index, data):
""" Catch and handle the view changes """
self.index = index
print(type(data))
#print(f'Data: {data.items()}, Index: {index},rv: {rv}, Type: {type(data)}')
return super(SelectableButton, self).refresh_view_attrs(rv, index, data)
def apply_selection(self, rv, index, is_selected):
self.selected = is_selected
def on_press(self):
popup = MessageBox(self)
popup.open()
def update_changes(self, txt):
self.text = txt
class RV(RecycleView):
#data_items = ListProperty([])
def __init__(self, **kwargs):
super(RV, self).__init__(**kwargs)
class WindowManager(ScreenManager):
pass
class UnreadWords(Screen):
unread_table = ObjectProperty(None)
rows = ListProperty([("Word", "Pronunciation", "English")])
def __init__(self, **kwargs):
super(UnreadWords, self).__init__(**kwargs)
def display_database(self):
con = sqlite3.connect('italian_unread.db')
cursor = con.cursor()
cursor.execute("SELECT Word, Pronunciation, English from Italian_a")
self.rows = cursor.fetchall()
kv = Builder.load_file("layout.kv")
class WordApp(App):
def build(self):
return kv
if __name__=="__main__":
WordApp().run()
layout.kv:
#: import NoTransition kivy.uix.screenmanager.NoTransition
#: include italian_a
<RV>:
viewclass: 'SelectableButton'
RecycleBoxLayout:
bcolor: 1,1,1,1
padding: "15dp", "5dp", "15dp", "15dp"
default_size: None, dp(25)
default_size_hint: 1, None
size_hint_y: None
height: self.minimum_height
orientation: 'vertical'
<SelectableButton>:
state_image: self.background_normal if self.state == 'normal' else self.background_down
disabled_image: self.background_disabled_normal if self.state == 'normal' else self.background_disabled_down
_scale: 1. if self.texture_size[0] < self.width else float(self.width) / self.texture_size[0]
orientation: 'horizontal'
canvas:
Color:
rgba: self.background_color
BorderImage:
border: self.border
pos: self.pos
size: self.size
source: self.disabled_image if self.disabled else self.state_image
PushMatrix
Scale:
origin: self.center
x: self._scale or 1.
y: self._scale or 1.
Color:
rgba: self.disabled_color if self.disabled else self.color
Rectangle:
texture: self.texture
size: self.texture_size
pos: int(self.center_x - self.texture_size[0] / 2.), int(self.center_y - self.texture_size[1] / 2.)
PopMatrix
<MessageBox>:
name: 'mbox'
lbl: lbl
title: ''
size_hint: None, None
size: 400, 400
on_open:
root.obj.update_changes(lbl.text)
BoxLayout:
orientation: 'vertical'
Label:
id: lbl
text: root.obj_text
Button:
size_hint: 1, 0.2
text: 'OK'
on_press:
root.dismiss()
WindowManager:
transition: NoTransition()
UnreadWords:
<UnreadWords>:
name: "unread"
unread_table: unread_table
BoxLayout:
orientation: "vertical"
rows: 4
cols: 1
GridLayout:
cols: 2
rows: 1
size_hint_y: 5
ScaleButton:
id: page2
text: "Page 2"
on_release:
app.root.current = "unread"
root.display_database()
GridLayout:
cols: 1
rows: 1
size_hint_y: 5
ScaleLabel:
text: "Unread Words"
size_hint_y: 5
color: (0/255., 0/255., 0/255., 1)
background_normal: ''
bcolor: (155/255., 155/255., 155/255., 1)
GridLayout:
cols: 1
rows: 1
size_hint_y: 80
BoxLayout:
id: unread_table
RV:
id: dat
viewclass: 'SelectableButton'
size_hint_y: 1
font_size: self.height * 0.5
data: [{'text': f'{entry[0], entry[1], entry[2]}'} for entry in root.rows]
#data: [{'text': f'{entry[0]}'} for entry in root.rows]
【问题讨论】: