轮播滑动方向的 Kivy RecycleView 不起作用
Posted
技术标签:
【中文标题】轮播滑动方向的 Kivy RecycleView 不起作用【英文标题】:Kivy RecycleView for Carousel slide direction not working 【发布时间】:2021-09-18 18:35:09 【问题描述】:每张 kivy 轮播幻灯片都由顶部的图像(带有复选框)和下方的文本组成。旋转木马的方向是“右”(一个接一个水平)。图像和文本数据通过循环视图提供给轮播。
最小代码结果 a) 每张幻灯片垂直堆叠; b) 复选框未显示。
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.recycleview import RecycleView
from kivy.properties import StringProperty, ListProperty, NumericProperty
Builder.load_string("""
<CarouselSlide>:
BoxLayout:
orientation: 'vertical'
size_hint_y: 1
AsyncImage:
source: root.tile
size_hint_y: 0.5
CheckBox:
id: cb
root_ref: root.index
on_press: app.on_checkbox_press(self, self.active, self.state, self.root_ref)
TextInput:
text: root.text
size_hint_y: 0.5
multiline: True
<CarouselScreen>:
name: 'carousel_screen'
Carousel:
direction: 'right'
ignore_perpendicular_swipes: True
size: root.width, root.height
RV:
id: rv
viewclass: 'CarouselSlide'
RecycleBoxLayout:
orientation: 'vertical'
size_hint_y: None
default_size_hint: 1, None
height: self.minimum_height
default_size: 1, root.height
""")
class CarouselScreen(Screen):
pass
class CarouselSlide(Screen):
tile = StringProperty('')
text = StringProperty('')
index = NumericProperty(-1)
cb_state = StringProperty('normal')
def __init__(self, **kwargs):
super(CarouselSlide, self).__init__(**kwargs)
self.bind(cb_state=self.set_cb_state)
def set_cb_state(self, carouselslide, cb_state_value):
self.ids.cb.state = cb_state_value
class RV(RecycleView):
data = ListProperty('[]')
def __init__(self, **kwargs):
super(RV, self).__init__(**kwargs)
self.get_slide_data()
def get_slide_data(self):
text="Ooh, a storm is threatening. My very life today. If I don't get some shelter. Ooh yeah I'm gonna fade away. War, children. It's just a shot away. It's just a shot away. War, children. It's just a shot away. It's just a shot away."
self.data = ['tile': 'The Rolling Stones', 'text': text, "index": i, "cb_state": 'normal' for i in range(41)]
class ThisApp(App):
def __init__(self, **kwargs):
super().__init__(**kwargs)
def build(self):
self.sm = ScreenManager()
self.sm.add_widget(CarouselScreen(name="carousel_screen"))
return self.sm
def on_checkbox_press(self, checkbox, active, state, root_ref):
if active:
print(active, state, root_ref)
else:
print(active, state, root_ref)
new_state = checkbox.state
checkbox.state = 'normal'
rv = self.root.get_screen('carousel_screen').ids.rv
rv.data[root_ref]['cb_state'] = new_state
rv.refresh_from_data()
if __name__ == "__main__":
ThisApp().run()
【问题讨论】:
【参考方案1】:我认为问题在于您将CheckBox
定义为AsyncImage
的子级。 AsyncImage
不是容器。尝试在 kv
中取消缩进 CheckBox
,并添加大小/位置属性:
<CarouselSlide>:
BoxLayout:
orientation: 'vertical'
size_hint_y: 1
AsyncImage:
source: root.tile
size_hint_y: 0.5
CheckBox:
id: cb
size_hint: None, None
size: 48, 48
pos_hint: 'center_x':0.5
root_ref: root.index
on_press: app.on_checkbox_press(self, self.active, self.state, self.root_ref)
TextInput:
text: root.text
size_hint_y: 0.5
multiline: True
【讨论】:
哎呀。我正在将 KivyMD 代码重写为 Kivy,有些事情有些不同。谢谢。 Wrt 到 Carousel 垂直堆叠幻灯片(direction='top')而不是水平(direction='right'),我尝试了不同的方式,但它坚持垂直堆叠?跨度>Carousel
的direction
无效,因为Carousel
只有一个孩子(RV
)。 RV
使用 RecycleBoxLayout
和 orientation
的 vertical
,这使得 Carousel
看起来是垂直的。
在RecycleBoxLayout中设置orientation='horizontal',每个CarouselSlide实例的内容被压扁成一张幻灯片。我试过 RecycleGridLayout 但结果是一样的。有办法解决这个奇怪的问题吗?
我认为问题在于您试图同时使用两种不同的解决方案。我的意见是您应该选择RecycleView
或Carousel
,但不能同时选择两者。 RecyclView
非常适合大量的CarouselSlides
,但Carousel
将适用于相当大的数字。分界线在哪里并不明显。以上是关于轮播滑动方向的 Kivy RecycleView 不起作用的主要内容,如果未能解决你的问题,请参考以下文章
Kivy 使用 RecycleView 的 CheckBox 问题