很抱歉,如果这是一个荒谬的问题。我是编程新手,到目前为止,我已经能够潜入已解决的问题中,但我找不到能解决该特定问题的任何东西,因此,我在这里遇到了第一个问题。堆栈社区。是的!
我正在使用SQLite数据库用Python / Kivy编写新鲜农产品库存管理应用程序。我有一个带有SelectableButton视图类的RecycleView列表,并将其包含在GridLayout中。
我在getItems
中有一个类方法(ItemList
),该方法从数据库中提取项目(字符串)和数量(实数),并将其添加到ListProperty
变量({ {1}}),这是data_all
应该从那里获取标签的地方。
在我的示例中,我已注释掉此方法,并以SelectableButton
应该采用的格式填充列表。实际上,在我撰写本文时,我想知道SQLite存储REAL值的方式与python如何存储浮点值之间是否存在重大差异。
无论如何,最终,我在“回收”视图列表中无法显示其数量旁边的项目。
最接近使它起作用的是制作一个2列getItems
,其左侧的项目名称为Button,而右侧的数量为Label。但是,当列表超出屏幕底部时,它们将彼此独立滚动,如下面的示例1所示。这不是我想要的,因为物品和数量应该紧挨着。
Python:
GridLayout
基维:
import kivy
from kivy.app import App
from kivy.uix.label import Label
from kivy.uix.gridlayout import GridLayout
from kivy.uix.textinput import TextInput
from kivy.uix.button import Button
from kivy.uix.widget import Widget
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.scrollview import ScrollView
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.recycleview.views import RecycleDataViewBehavior
from kivy.properties import ObjectProperty, BooleanProperty, ListProperty, StringProperty, ObjectProperty, NumericProperty, DictProperty
from kivy.uix.recyclegridlayout import RecycleGridLayout
from kivy.uix.behaviors import FocusBehavior
from kivy.uix.recycleview.layout import LayoutSelectionBehavior
from kivy.uix.popup import Popup
import string
#import sqlite3
class EditItemPopup(Popup):
obj = ObjectProperty(None)
obj_text = StringProperty("")
#The full code also includes quantity data to be displayed here, but that's irrelevant to the question
def __init__(self, obj, **kwargs):
super(EditItemPopup, self).__init__(**kwargs)
self.obj = obj
self.obj_text = self.obj.text
class SelectableRecycleGridLayout(FocusBehavior, LayoutSelectionBehavior,
RecycleGridLayout):
''' Adds selection and focus behaviour to the view. '''
class SelectableButton(RecycleDataViewBehavior, Button):
''' Add selection support to the Button '''
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
return super(SelectableButton, self).refresh_view_attrs(rv, index, data)
def on_touch_down(self, touch):
''' Add selection on touch down '''
if super(SelectableButton, self).on_touch_down(touch):
return True
if self.collide_point(*touch.pos) and self.selectable:
return self.parent.select_with_touch(self.index, touch)
def apply_selection(self, rv, index, is_selected):
''' Respond to the selection of items in the view. '''
self.selected = is_selected
def on_press(self):
popup = EditItemPopup(self)
popup.open()
def update_changes(self, txt):
self.text = txt
class ItemList(Widget):
'''User selects, adds, edits, and deletes items and quanitities'''
#this is how the data is extracted from the SQLite db
data_all = ListProperty(['Apples', 3.0, 'Bananas', 12.0, 'Lettuce', 16.5, 'Asparagus', 3.0])
def __init__(self, **kwargs):
super(ItemList, self).__init__(**kwargs)
# self.getItems()
return
#This method, and the invocation for it in the __init__ methd is how I would typically pull data from the SQLite db. I've left it commented here and open to constructive criticism
# def getItems(self):
# c.execute("SELECT item, quantity FROM itemTable ORDER BY item ASC")
# rows = c.fetchall()
# for row in rows:
# for col in row:
# self.data_all.append(col)
class ColStock(App):
def build(self):
return ItemList()
if __name__ == "__main__":
ColStock().run()
我尝试解决此问题,而不是创建一个GridLayout列,将项目名称,字符串分隔符和数量都放在同一按钮上,并在<EditItemPopup>:
title: "Edit Item"
size_hint: None, None
size: 400, 500
auto_dismiss: False
BoxLayout:
orientation: "vertical"
GridLayout:
size_hint_y: None
height: 50
cols: 3
Label:
text: root.obj_text
Button:
size_hint_y: None
height: 50
text: "OK, thanks"
on_press: root.dismiss()
<SelectableButton>:
# Draw a background to indicate selection
canvas.before:
Color:
rgba: (.0, 0.9, .1, .3) if self.selected==True else (0, 0, 0, 0)
Rectangle:
pos: self.pos
size: self.size
<ItemList>:
GridLayout:
size: root.width,root.height
cols: 2
RecycleView:
viewclass: 'SelectableButton'
data: [{'text': str(x)} for x in root.data_all[0::2]]
SelectableRecycleGridLayout:
cols: 1
default_size: None, dp(30)
default_size_hint: 1, None
size_hint_y: None
height: self.minimum_height
orientation: 'vertical'
multiselect: True
touch_multiselect: True
RecycleView:
viewclass: 'Label'
data: [{'text': str(x)} for x in root.data_all[1::2]]
RecycleGridLayout:
cols: 1
default_size: None, dp(30)
default_size_hint: 1, None
size_hint_y: None
height: self.minimum_height
orientation: 'vertical'
的init方法中使用rpartition("......qty: ')
进行提取仅商品名称。
但是,我尝试过的所有操作都会返回错误,通常是TypeError。
Python:
EditItemPopup
基维:
import kivy
from kivy.app import App
from kivy.uix.label import Label
from kivy.uix.gridlayout import GridLayout
from kivy.uix.textinput import TextInput
from kivy.uix.button import Button
from kivy.uix.widget import Widget
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.scrollview import ScrollView
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.recycleview.views import RecycleDataViewBehavior
from kivy.properties import ObjectProperty, BooleanProperty, ListProperty, StringProperty, ObjectProperty, NumericProperty, DictProperty
from kivy.uix.recyclegridlayout import RecycleGridLayout
from kivy.uix.behaviors import FocusBehavior
from kivy.uix.recycleview.layout import LayoutSelectionBehavior
from kivy.uix.popup import Popup
import string
#import sqlite3
class EditItemPopup(Popup):
obj = ObjectProperty(None)
obj_text = StringProperty("")
item_name = StringProperty("")
item_qty = StringProperty("")
#The full code also includes quantity data to be displayed here, but that's irrelevant to the question
def __init__(self, obj, **kwargs):
super(EditItemPopup, self).__init__(**kwargs)
self.obj = obj
self.obj_text = self.obj.text
self.item_tuple = self.obj_text.rpartition("......qty: ")
self.item_name = self.item_tuple[0]
self.item_qty = self.item_tuple[2]
class SelectableRecycleGridLayout(FocusBehavior, LayoutSelectionBehavior,
RecycleGridLayout):
''' Adds selection and focus behaviour to the view. '''
class SelectableButton(RecycleDataViewBehavior, Button):
''' Add selection support to the Button '''
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
return super(SelectableButton, self).refresh_view_attrs(rv, index, data)
def on_touch_down(self, touch):
''' Add selection on touch down '''
if super(SelectableButton, self).on_touch_down(touch):
return True
if self.collide_point(*touch.pos) and self.selectable:
return self.parent.select_with_touch(self.index, touch)
def apply_selection(self, rv, index, is_selected):
''' Respond to the selection of items in the view. '''
self.selected = is_selected
def on_press(self):
popup = EditItemPopup(self)
popup.open()
def update_changes(self, txt):
self.text = txt
class ItemList(Widget):
'''User selects, adds, edits, and deletes items and quanitities'''
#this is how the data is extracted from the SQLite db
data_all = ListProperty(['Apples', 3.0, 'Bananas', 12.0, 'Lettuce', 16.5, 'Asparagus', 3.0])
def __init__(self, **kwargs):
super(ItemList, self).__init__(**kwargs)
# self.getItems()
return
#This method, and the invocation for it in the __init__ methd is how I would typically pull data from the SQLite db. I've left it commented here and open to constructive criticism
# def getItems(self):
# c.execute("SELECT item, quantity FROM itemTable ORDER BY item ASC")
# rows = c.fetchall()
# for row in rows:
# for col in row:
# self.data_all.append(col)
class ColStock(App):
def build(self):
return ItemList()
if __name__ == "__main__":
ColStock().run()
我可能已经违反了编程中的所有约定,并且我知道这是黑客,但是我对任何可行的方法都感到满意。预先感谢任何可以阐明这一点的人。 :)
答案 0 :(得分:0)
因此,我在此问题上停留了大约2到3周,而我在寻求S.E方面的帮助的那一天就是我通过反复试验找到了适合我需要的解决方案的那一天。
我可以在kivy文件中使用以下语法,该文件通过迭代const links = document.querySelectorAll('li a');
links.forEach( function(el) {
const parent = el.parentNode.parentNode.previousElementSibling;
el.addEventListener('click', function() {
if (el.classList.contains('selected')) {
if (parent !== null) {
parent.style.display = 'block';
}
el.nextElementSibling.style.display = 'none';
el.classList.remove('selected');
} else {
if (el.nextElementSibling !== null) {
el.nextElementSibling.style.display = 'block';
el.classList.add('selected');
}
if (parent !== null && el.nextElementSibling !== null) {
parent.style.display = 'none';
}
}
}, false);
});
列表中的每一对来将项目和数量添加到每个SelectableButton中:
data_all
然后我将以下内容添加到弹出窗口的 init 方法(python文件)中,以仅提取标签的项目名称:
data: [{'text': str(x) + "......qty: " + str(y)} for x,y in zip(root.data_all[0::2],root.data_all[1::2])]
然后self.obj_tuple = self.obj_text.rpartition("......qty: ")
self.item_name = self.obj_tuple[0]
也可以用于引用SQLite数据库中的正确行。
当然也欢迎提出其他建议,但是我希望这对面临类似问题的人有所帮助。