我想将(csv-)表的数据放入kivy recycleview。
如果我为kv中的标签分配了固定的文本,我设法在一行中插入多列,但是我无法用字典列表中的数据填充标签来填充标签。到目前为止,这是我用来测试概念的代码:
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.recycleview import RecycleView
from kivy.uix.boxlayout import BoxLayout
import csv
items = [{'SP1': 'Artikelnummer', 'SP2': 'Name', 'SP3': 'Groesse'},
{'SP1': '510001', 'SP2': 'Big Pump', 'SP3': '1.50 L'},
{'SP1': '523001', 'SP2': 'Leonie Still', 'SP3': '1.50 L'},
{'SP1': '641301', 'SP2': 'Cola Mix', 'SP3': '1.50 L'}
]
class Tabelle(BoxLayout):
def __init__(self, **kwargs):
super(Tabelle, self).__init__(**kwargs)
def insert_SP(self, data):
for i in data:
self.spalte1_SP = i['SP1']
#print(self.spalte1_SP)
self.spalte2_SP = i['SP2']
self.spalte3_SP = i['SP3']
Builder.load_string('''
<Tabelle>:
orientation: 'horizontal'
spalte1_SP: 'spalte1'
spalte2_SP: 'spalte2'
spalte3_SP: 'spalte3'
Label:
id: Spalte1
text: root.spalte1_SP
Label:
id: Spalte2
text: root.spalte2_SP
Label:
id: Spalte3
text: root.spalte3_SP
<RV>:
viewclass: 'Tabelle'
RecycleBoxLayout:
default_size: None, dp(20)
default_size_hint: 1, None
size_hint_y: None
height: self.minimum_height
orientation: 'vertical'
''')
class RV(RecycleView):
def __init__(self, **kwargs):
super(RV, self).__init__(**kwargs)
#self.data = []
x = Tabelle()
x.insert_SP(items)
class TestApp(App):
def build(self):
return RV()
if __name__ == '__main__':
TestApp().run()
我希望在3列中看到项中的数据,但是由于某些原因它们仍然为空。
答案 0 :(得分:0)
该字段为空,因为未填充data
。
class Tabelle()
中的所有编码pass
添加到class Tabelle()
__init__()
中的class RV()
的构造函数中self.data = [{'spalte1_SP': str(x['SP1']), 'spalte2_SP': str(x['SP2']), 'spalte3_SP': str(x['SP3'])} for x in items]
通过处理data(基本上是一个列表)来生成视图 的字典,并使用这些字典生成视图类的实例 根据需要。
data
当前视图适配器使用的数据。这是字典列表 其键映射到视图类的相应属性名称。
data是AliasProperty,它获取并设置用于生成的数据 视图。
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.recycleview import RecycleView
from kivy.uix.boxlayout import BoxLayout
items = [{'SP1': 'Artikelnummer', 'SP2': 'Name', 'SP3': 'Groesse'},
{'SP1': '510001', 'SP2': 'Big Pump', 'SP3': '1.50 L'},
{'SP1': '523001', 'SP2': 'Leonie Still', 'SP3': '1.50 L'},
{'SP1': '641301', 'SP2': 'Cola Mix', 'SP3': '1.50 L'}
]
class Tabelle(BoxLayout):
pass
Builder.load_string('''
<Tabelle>:
orientation: 'horizontal'
spalte1_SP: 'spalte1'
spalte2_SP: 'spalte2'
spalte3_SP: 'spalte3'
Label:
id: SP1
text: root.spalte1_SP
Label:
id: SP2
text: root.spalte2_SP
Label:
id: SP3
text: root.spalte3_SP
<RV>:
viewclass: 'Tabelle'
RecycleBoxLayout:
default_size: None, dp(20)
default_size_hint: 1, None
size_hint_y: None
height: self.minimum_height
orientation: 'vertical'
''')
class RV(RecycleView):
def __init__(self, **kwargs):
super(RV, self).__init__(**kwargs)
self.data = [{'spalte1_SP': str(x['SP1']), 'spalte2_SP': str(x['SP2']), 'spalte3_SP': str(x['SP3'])} for x in items]
class TestApp(App):
def build(self):
return RV()
if __name__ == '__main__':
TestApp().run()
答案 1 :(得分:0)
基于之前的解决方案,这里的代码更容易解释。此外,其中一列是复选框。
Python 文件:
cmake_minimum_required (VERSION 3.8)
set(PROJECT GUI_Engine)
add_executable (${PROJECT} "./src/driver/main.cpp")
set(HEADER_FILES ./src/include)
set(DEC_FILES ./src/lib)
set(PKGPATH C:/dev/vcpkg/packages)
add_library(engine ${DEC_FILES}/engine.cpp ${HEADER_FILES}/engine.hpp)
list(APPEND CMAKE_PREFIX_PATH ${PKGPATH}/sdl2_x64-windows)
find_package(SDL2 CONFIG REQUIRED)
target_link_libraries(${PROJECT} PRIVATE engine SDL2::SDL2main)
target_link_libraries(engine PRIVATE SDL2::SDL2)
list(APPEND CMAKE_PREFIX_PATH ${PKGPATH}/glew_x64-windows)
find_package(GLEW REQUIRED)
target_link_libraries(engine PRIVATE GLEW::GLEW)
KV 文件:
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.gridlayout import GridLayout
# data
items = [{'number': '510001', 'name': 'Big Pump', 'size': '1.50 L', 'in_stock': True},
{'number': '523001', 'name': 'Leonie Still', 'size': '1.60 L', 'in_stock': False},
{'number': '641301', 'name': 'Apple Mix', 'size': '1.30 L', 'in_stock': True},
{'number': '681301', 'name': 'Orange Mix', 'size': '1.40 L', 'in_stock': True}
]
class MultiFieldLine(BoxLayout):
# class layout defined in kv file
pass
class AppGUI(GridLayout):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.rv.data = [{'label_1': str(x['number']), 'label_2': str(x['name']), 'label_3': str(x['size']), 'checkbox_1': x['in_stock']} for x in items]
class ExploreRecycleViewMultipleFieldApp(App):
def build(self):
return AppGUI()
if __name__ == '__main__':
ExploreRecycleViewMultipleFieldApp().run()
下面的版本添加了行选择以及名称列的更大标签宽度和 gui 类中每次选择行时调用的方法。:
Python 文件:
<MultiFieldLine>:
orientation: 'horizontal'
label_1: ''
label_2: ''
label_3: ''
checkbox_1: False
Label:
text: root.label_1
Label:
text: root.label_2
Label:
text: root.label_3
CheckBox:
active: root.checkbox_1
<AppGUI>: # inherit from GridLayout
rv: rv_id
cols: 1
rows: 2
GridLayout: # col titles
cols: 4
rows: 1
size_hint_y: 0.04
Label:
text: 'Number'
Label:
text: 'Name'
Label:
text: 'Size'
Label
text: 'In stock'
GridLayout: # data
cols: 1
rows: 1
size_hint_y: 0.96
RecycleView:
id: rv_id
viewclass: 'MultiFieldLine'
RecycleBoxLayout:
default_size: None, dp(20)
default_size_hint: 1, None
size_hint_y: None
height: self.minimum_height
orientation: 'vertical'
KV 文件:
from kivy.app import App
from kivy.properties import BooleanProperty
from kivy.uix.behaviors import FocusBehavior
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.gridlayout import GridLayout
# data
from kivy.uix.recycleboxlayout import RecycleBoxLayout
from kivy.uix.recycleview.layout import LayoutSelectionBehavior
from kivy.uix.recycleview.views import RecycleDataViewBehavior
items = [{'number': '510001', 'name': 'Big Pump', 'size': '1.50 L', 'in_stock': True},
{'number': '523001', 'name': 'Leonie Still very, very,very long, long name', 'size': '1.60 L', 'in_stock': False},
{'number': '641301', 'name': 'Apple Mix', 'size': '1.30 L', 'in_stock': True},
{'number': '681301', 'name': 'Orange Mix', 'size': '1.40 L', 'in_stock': True}
]
class MultiFieldLine(RecycleDataViewBehavior, BoxLayout):
''' class layout defined in kv file '''
index = None
selected = BooleanProperty(False)
selectable = BooleanProperty(True)
def refresh_view_attrs(self, rv, index, data):
''' Catch and handle the view changes '''
self.rv = rv
self.appGUI = rv.appGUI
self.index = index
return super(MultiFieldLine, self).refresh_view_attrs(
rv, index, data)
def on_touch_down(self, touch):
''' Add selection on touch down '''
if super(MultiFieldLine, 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):
# instance variable used in .kv file to change the selected item
# color !
self.selected = is_selected
if is_selected:
self.appGUI.outputSelectedData(rv.data[index])
class SelectableRecycleBoxLayout(FocusBehavior, LayoutSelectionBehavior,
RecycleBoxLayout):
''' Adds selection and focus behaviour to the view. '''
# required to authorise unselecting a selected item
touch_deselect_last = BooleanProperty(True)
class AppGUI(GridLayout):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.rv.data = [{'label_1': str(x['number']), 'label_2': str(x['name']), 'label_3': str(x['size']), 'checkbox_1': x['in_stock']} for x in items]
def outputSelectedData(self, data):
# method called when a line is selected
print(data)
class ExploreRecycleViewMultipleFieldBoxLayoutApp(App):
def build(self):
return AppGUI()
if __name__ == '__main__':
ExploreRecycleViewMultipleFieldBoxLayoutApp().run()