kivy recycleview用于转盘滑动方向不工作

xienkqul  于 2021-09-13  发布在  Java
关注(0)|答案(1)|浏览(311)

每个kivy carousel幻灯片由顶部的图像(带有复选框)和下面的文本组成。转盘的方向为“右”(一个接一个水平方向)。图像和文本数据通过recycleview馈送到旋转木马。
最小代码结果为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()
llycmphe

llycmphe1#

我相信问题在于你正在定义 CheckBox 作为一个孩子 AsyncImage . 这个 AsyncImage 不打算用作容器。尝试取消缩进 CheckBox 在你的 kv ,并添加大小/位置属性:

<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

相关问题