轮播滑动方向的 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'),我尝试了不同的方式,但它坚持垂直堆叠?跨度> Carouseldirection 无效,因为Carousel 只有一个孩子(RV)。 RV 使用 RecycleBoxLayoutorientationvertical,这使得 Carousel 看起来是垂直的。 在RecycleBoxLayout中设置orientation='horizo​​ntal',每个CarouselSlide实例的内容被压扁成一张幻灯片。我试过 RecycleGridLayout 但结果是一样的。有办法解决这个奇怪的问题吗? 我认为问题在于您试图同时使用两种不同的解决方案。我的意见是您应该选择RecycleViewCarousel,但不能同时选择两者。 RecyclView 非常适合大量的CarouselSlides,但Carousel 将适用于相当大的数字。分界线在哪里并不明显。

以上是关于轮播滑动方向的 Kivy RecycleView 不起作用的主要内容,如果未能解决你的问题,请参考以下文章

Kivy 使用 RecycleView 的 CheckBox 问题

RecycleView 导致 Kivy 可执行文件崩溃

在 Kivy 中使用 RecycleView 的自定义小部件的对齐问题

硅谷新闻5--顶部新闻轮播图事件处理

Flexslider图片轮播文字图片相结合滑动切换效果

Kivy 滚动条滚动方向与鼠标