【问题标题】:Making a widget swipeable in kivy在 kivy 中制作可滑动的小部件
【发布时间】:2021-05-27 08:48:45
【问题描述】:

我正在尝试在 FLoatLayout 内创建一组可滑动并上下移动的小部件。但是,就像展示柜或画廊小部件一样,我似乎无法配置滑动功能。我想也许我可以使用 Carousel 小部件来实现这一点,这最终会更好,因为它具有 swiper 所需的所有功能和行为,但我无法找到让项目流血的方法因为那是我想要的样子。有没有办法可以将滑动事件绑定到我的浮动布局?我的代码:

from kivy.app import App
from kivy.uix.floatlayout import FloatLayout
from kivy.lang import Builder
from kivy.core.window import Window
from kivy.animation import Animation

Window.minimum_width, Window.minimum_height = Window.size
Builder.load_string('''
<Item@Button>:
    size_hint: .5, .5
    font_size: 32
<Swiper>:
    Item:
        text: "Button 1"
        pos_hint: {"center_x": .5, "center_y": len(self.parent.children) * .5}
        on_release: root.change_pos(self)
    Item:
        text: "Button 2"
        pos_hint: {"center_x": .5, "center_y": (len(self.parent.children) - 1) * .5}
        on_release: root.change_pos(self)
    Item:
        text: "Button 3"
        pos_hint: {"center_x": .5, "center_y": (len(self.parent.children) - 2) * .5}
        on_release: root.change_pos(self)
    Item:
        text: "Button 4"
        pos_hint: {"center_x": .5, "center_y": (len(self.parent.children) - 3) * .5}
        on_release: root.change_pos(self)
    Item:
        text: "Button 5"
        pos_hint: {"center_x": .5, "center_y": (len(self.parent.children) - 4) * .5}
        on_release: root.change_pos(self)
    Item:
        text: "Button 6"
        pos_hint: {"center_x": .5, "center_y": (len(self.parent.children) - 5) * .5}
        on_release: root.change_pos(self)
''')


class Swiper(FloatLayout):
    focused_index = 0
    def change_pos(self, instance):
        instance_index = self.children.index(instance)
        if instance_index < self.focused_index:
            for item in self.children:
                Animation(pos_hint={"center_y": item.pos_hint["center_y"]+.5}).start(item)
        elif instance_index > self.focused_index:
            for item in self.children:
                Animation(pos_hint={"center_y": item.pos_hint["center_y"]-.5}).start(item)
        else:
            print("item already has focus")
        self.focused_index = instance_index


class MainApp(App):
    def build(self):
        return Swiper()


if __name__ == "__main__":
    MainApp().run()

【问题讨论】:

    标签: python python-3.x kivy kivy-language


    【解决方案1】:

    你可以像这样使用Carousel

    from kivy.app import App
    from kivy.lang import Builder
    from kivy.core.window import Window
    
    Window.minimum_width, Window.minimum_height = Window.size
    
    kv = Builder.load_string('''
    <Item@Button>:
        size_hint: .5, .5
        pos_hint: {"center_x": .5, "center_y": .5}
        font_size: 32
    Carousel:
        direction: 'right'
        Item:
            text: "Button 1"
        Item:
            text: "Button 2"
        Item:
            text: "Button 3"
        Item:
            text: "Button 4"
        Item:
            text: "Button 5"
        Item:
            text: "Button 6"
    ''')
    
    
    class MainApp(App):
        def build(self):
            return kv
    
    
    if __name__ == "__main__":
        MainApp().run()
    

    另一种可能性是在ScrollView 中使用GridLayout

    from kivy.app import App
    from kivy.lang import Builder
    from kivy.core.window import Window
    
    Window.minimum_width, Window.minimum_height = Window.size
    
    kv = Builder.load_string('''
    <Item@Button>:
        size_hint: None, None
        size: self.texture_size[0] + 100, self.texture_size[1] + 100
        font_size: 32
    ScrollView:
        GridLayout:
            cols: 1
            size_hint_y: None
            height: self.minimum_height
            AnchorLayout:
                size_hint_y: None
                height: b1.height
                Item:
                    id: b1
                    text: "Button 1"
            AnchorLayout:
                size_hint_y: None
                height: b2.height
                Item:
                    id: b2
                    text: "Button 2"
            AnchorLayout:
                size_hint_y: None
                height: b3.height
                Item:
                    id: b3
                    text: "Button 3"
            AnchorLayout:
                size_hint_y: None
                height: b4.height
                Item:
                    id: b4
                    text: "Button 4"
            AnchorLayout:
                size_hint_y: None
                height: b5.height
                Item:
                    id: b5
                    text: "Button 5"
            AnchorLayout:
                size_hint_y: None
                height: b6.height
                Item:
                    id: b6
                    text: "Button 6"
    ''')
    
    
    class MainApp(App):
        def build(self):
            return kv
    
    
    if __name__ == "__main__":
        MainApp().run()
    

    【讨论】:

    • 我希望项目能够像我使用 FloatLayout 制作的那样相互融合,我如何使用轮播来实现这一点?
    • Carousel 一次只显示一个Item。也许你想要的是一个只有一列的GridLayout
    • 究竟如何使用 GridLayout 实现?这似乎不可行,因为我也想为它制作动画。你能演示一下吗?
    【解决方案2】:

    我认为这个网站有你的答案

    https://github.com/kivy-garden/garden.swipetodelete#:~:text=SwipeToDelete%20widget%20is%20built%20on,commit%20adds%20some%20new%20features.

    SwipeBehaviour 属性

    swipe_distance - 滑动前移动的距离。数值属性(20)

    swipe_timeout - 允许触发 swipe_distance 的超时(以毫秒为单位)。数值属性(55)

    swipe_rect_x - 允许滑动的轴对齐边界矩形的 X 位置。数值属性(0)

    swipe_rect_y - 允许滑动的轴对齐边界矩形的 Y 位置。数值属性(0)

    swipe_rect_width - 允许滑动的轴对齐边界矩形的宽度。数值属性(100)

    swipe_rect_height - 允许滑动的轴对齐边界矩形的高度。数值属性(100)

    swipe_rectangle - 允许滑动的轴对齐边界矩形的位置和大小。 ReferenceListProperty(swipe_rect_x, swipe_rect_y, swipe_rect_width, swipe_rect_height)

    remove_from_left - 用户可以选择是否从左侧移除小部件。

    remove_from_right - 用户可以选择是否从右侧移除小部件。

    animation_type - 返回时用于不同的动画。

    animation_duration - 动画的持续时间

    right_percentage - 决定用户向右滑动时要删除的限制。

    left_percentage - 决定用户向左侧滑动时要删除的限制。

    move_to - 移动小部件

    opacity_reduction_rate - 更改不透明度降低的方式。

    【讨论】:

      猜你喜欢
      • 2017-09-18
      • 2019-09-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多