Kivy开发疑问:MDSwiper组件为何出现重复标签?
问题描述
我正在尝试制作一个包含列表项的MDSwiper组件,但始终出现重复标签。我尝试调整多种布局以及SwiperItem的插入方式,未在网上找到类似问题案例。我是Kivy新手,推测是简单问题。
Python代码
from kivy.app import App from kivy.lang import Builder from kivy.uix.widget import Widget from kivymd.app import MDApp from kivymd.uix.list import TwoLineListItem from kivymd.uix.swiper.swiper import MDSwiperItem class MySwiperItem(MDSwiperItem): pass class DemoApp(MDApp): def build(self): self.theme_cls.theme_style = "Dark" return Builder.load_file('demo.kv') def on_start(self): SwiperTest = MySwiperItem() SwiperTest.ids.header.text = "test" SwiperTest.ids.list.add_widget( TwoLineListItem( text = "text1", secondary_text = "text2" ) ) self.root.ids.swiper.add_widget(SwiperTest) if __name__ == '__main__': DemoApp().run()
Kv语言文件
<DrawerClickableItem@MDNavigationDrawerItem> focus_color: "#e7e4c0" text_color: "#4a4939" icon_color: "#4a4939" ripple_color: "#c5bdd2" selected_color: "#0c6c4d" <DrawerLabelItem@MDNavigationDrawerItem> text_color: "#4a4939" icon_color: "#4a4939" focus_behavior: False selected_color: "#4a4939" _no_ripple_effect: True <MySwiperItem>: orientation: "vertical" MDLabel: id: header font_style: "H5" size_hint_y: None height: self.texture_size[1] + dp(40) pos_hint: {"center_x": .5, "top": 1} md_bg_color: "grey" MDScrollView: MDList: id: list MDScreen: MDNavigationLayout: MDScreenManager: MDScreen: orientation: "vertical" MDTopAppBar: id: nav_bar title: "Smart Indoor Watering System" elevation: 4 pos_hint: {"top": 1} md_bg_color: "#e7e4c0" specific_text_color: "#4a4939" left_action_items: [["menu", lambda x: nav_drawer.set_state("open")]] MDSwiper: id: swiper size_hint_y: None height: root.height - nav_bar.height - dp(40) y: root.height - self.height - nav_bar.height - dp(20) MDNavigationDrawer: id: nav_drawer radius: (0, 16, 16, 0) MDNavigationDrawerMenu: MDNavigationDrawerHeader: title: "Header title" title_color: "#4a4939" text: "Header text" spacing: "4dp" padding: "12dp", 0, 0, "56dp" MDNavigationDrawerLabel: text: "Mail" DrawerClickableItem: icon: "gmail" right_text: "+99" text_right_color: "#4a4939" text: "Inbox" DrawerClickableItem: icon: "send" text: "Outbox" MDNavigationDrawerDivider: MDNavigationDrawerLabel: text: "Labels" DrawerLabelItem: icon: "information-outline" text: "Label" DrawerLabelItem: icon: "information-outline" text: "Label"
解决方案
问题根源在于MDSwiper默认开启了**循环滑动(loop)**模式,它会自动复制首尾的SwiperItem来实现无缝循环效果,这就导致你添加的单个MySwiperItem被重复显示。
只需要在Kv文件的MDSwiper配置里添加loop: False即可解决:
MDSwiper: id: swiper size_hint_y: None height: root.height - nav_bar.height - dp(40) y: root.height - self.height - nav_bar.height - dp(20) loop: False # 添加这一行关闭循环模式
另外补充一点:你的MySwiperItem继承自MDSwiperItem,而MDSwiperItem本身并不是BoxLayout,在Kv里直接设置orientation: "vertical"其实是无效的,正确的做法是在MySwiperItem内部嵌套一个BoxLayout来承载子控件:
<MySwiperItem>: BoxLayout: orientation: "vertical" MDLabel: id: header font_style: "H5" size_hint_y: None height: self.texture_size[1] + dp(40) pos_hint: {"center_x": .5, "top": 1} md_bg_color: "grey" MDScrollView: MDList: id: list
这样能确保布局的层级正确,避免潜在的布局异常问题。
内容的提问来源于stack exchange,提问作者Ash Ketchup
相关产品推荐
相关产品推荐

