【发布时间】:2018-04-20 06:16:47
【问题描述】:
最近我一直在努力在 kivy 中使用 RecycleView。我做了很多测试,有点困惑。
我的目标
我想创建一个回收视图,其中每个Row 包含很少的Label(即列),但列数是动态设置的(当然所有行都相同)。通常,我有一个数据库,我想显示表,但我想动态更改我显示的列。
有类似的问题,但它们都处理固定数量的值来设置。
什么有效
- 如果列数固定,则可以使用属性链接值
- 我可以使用
add_widget动态添加小部件
什么不起作用
- 如果动态添加单元格,我无法将 kv 小部件中的 value 内容链接到 python 变量
- 如果 Label 小部件的数量是固定的,我可以动态更新内容(如示例),但不能直接初始化。
这是我尝试过的所有不同可能性的示例:
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.boxlayout import BoxLayout
from kivy.properties import StringProperty, ObjectProperty
from kivy.uix.label import Label
from kivy.uix.recycleview import RecycleView
kv = """
<Row>:
id: row
canvas.before:
Color:
rgba: 0.5, 0.5, 0.5, 1
Rectangle:
size: self.size
pos: self.pos
value1: ''
value2: ''
value3: ''
value4: ''
value5: ''
Label: #Label 1
text: root.value1
<Test>:
canvas:
Color:
rgba: 0.3, 0.3, 0.3, 1
Rectangle:
size: self.size
pos: self.pos
orientation: 'vertical'
GridLayout:
cols: 3
rows: 2
size_hint_y: None
height: dp(108)
padding: dp(8)
spacing: dp(16)
Button:
text: 'Update list'
on_press: root.update()
RecycleView:
id: rvlist
scroll_type: ['bars', 'content']
scroll_wheel_distance: dp(114)
bar_width: dp(10)
viewclass: 'Row'
RecycleBoxLayout:
default_size: None, dp(56)
default_size_hint: 1, None
size_hint_y: None
height: self.minimum_height
orientation: 'vertical'
spacing: dp(2)
"""
Builder.load_string(kv)
class Row(BoxLayout):
constant_value = 'constant content from class data'
value1 = StringProperty('default 1')
value2 = StringProperty('default 2')
value3 = StringProperty('default 3')
value4 = StringProperty('default 4')
value5 = StringProperty('default 5')
# value5,....
def __init__(self,**kwargs):
super().__init__(**kwargs)
self.add_widget(Label(text = 'constant content')) # Label 2
self.add_widget(Label(text = self.constant_value)) #Label 3
self.add_widget(Label(text = self.value4)) # Label 4
self.add_widget(Label(text = self.value5)) # Label 5
for x in kwargs:
self.add_widget(Label(text = 'content from **kwargs'))# Label 6
class Test(BoxLayout):
def __init__(self,**kwargs):
super().__init__(**kwargs)
self.ids.rvlist.data = [{'value1': 'init content from parent class',
'value4': 'init content from parent class'} for x in range(15)]
def update(self):
self.ids.rvlist.data = [{'value1': 'updated content from parent class dynamic widget',
'value4': 'updated content from parent class dynamic widget',
'value5': 'updated content from parent class static widget'} for x in range(15)]
class TestApp(App):
def build(self):
return Test()
if __name__ == '__main__':
TestApp().run()
行为如下:
- Label1:与文档中的定义相同。这很好用,但我需要在 Row 类中定义与列的最大可能值一样多的值,并且只使用其中的几个。它看起来有点骇人听闻...
- Label2:按预期工作。这是一个恒定的内容。但这不是我需要的(我想用动态生成的内容填充这些行)
- Label3:Label2 的变体,不是我需要的。但有效。
-
Label4:这里的标签是在初始化时设置的。 初始化和更新不起作用,可能是因为尚未创建小部件,因此
self.value4尚不存在。有解决方法吗? - Label5:标签在更新时设置。 初始化和更新都不起作用。与 4 类似。
-
Label6:甚至没有创建。我原以为
data将是传递给类进行初始化的参数之一,这样我就可以为每个数据创建一个标签。我猜这将是最理想的情况。
它提出了以下问题:
- 如何动态创建一个 kv 属性并将其链接到另一个属性? (类似于self.add_widget(Label(value5 = parent.value5,text = self.value5))。这将允许在初始化后更新文本(就像我的 label1 不知何故)
- 初始化期间如何访问data?
- 如何使用self.value来初始化Label?
我希望它足够清楚......我自己也很困惑。
【问题讨论】:
标签: python kivy kivy-language