Kivy/KivyMD中如何实现需先点击首标签按钮才可切换其他标签
问题原因
on_tab_switch是标签切换动作触发、切换动画执行过程中才回调的事件,此时直接调用switch_tab会和正在进行的切换流程冲突,导致跳回操作被拦截,必须等当前动画结束后第二次点击才能生效。
修复方法
通过 Kivy 时钟调度把跳回 Tab 0 的操作延迟到下一帧执行,避开当前切换流程的冲突即可,修改点如下:
- 导入 Kivy 时钟模块:
from kivy.clock import Clock - 修改
on_tab_switch方法中的跳转逻辑,将直接调用switch_tab改为延迟调度执行。
修改后完整可运行代码
from kivy.lang import Builder from kivy.clock import Clock from kivymd.app import MDApp from kivymd.uix.floatlayout import MDFloatLayout from kivymd.uix.button import MDRaisedButton from kivymd.uix.tab import MDTabsBase from kivymd.toast import toast KV = ''' MDBoxLayout: orientation: "vertical" MDToolbar: title: "标签页示例" MDTabs: id: tabs on_tab_switch: app.on_tab_switch(*args) <Tab> MDLabel: id: label text: "Tab 0" halign: "center" <Tab4test> MDLabel: id: label text: "Tab 0" halign: "center" MDRaisedButton: text: "点击我!!!" on_release: root.change_flag() ''' class Tab(MDFloatLayout, MDTabsBase): '''实现标签页内容的类''' class Tab4test(MDFloatLayout, MDTabsBase): '''实现标签页内容的类''' def change_flag(self): MDApp.get_running_app().flag =1 toast("flag值已修改为1!") class Example(MDApp): flag = 0 def build(self): return Builder.load_string(KV) def on_start(self): self.root.ids.tabs.add_widget(Tab4test(title=f"Tab 0")) for i in range(1, 3): self.root.ids.tabs.add_widget(Tab(title=f"Tab {i}")) print(self.flag) def on_tab_switch( self, instance_tabs, instance_tab, instance_tab_label, tab_text ): '''切换标签页时调用 :type instance_tabs: <kivymd.uix.tab.MDTabs object>; :param instance_tab: <__main__.Tab object>; :param instance_tab_label: <kivymd.uix.tab.MDTabsLabel object>; :param tab_text: 标签页的文本或图标名称; ''' instance_tab.ids.label.text = tab_text print(self.flag) title = instance_tab.title if title != f"Tab 0" and self.flag == 0: toast("请先点击Tab 0中的按钮!", duration=3) # 延迟下一帧执行跳转,避开当前切换动画冲突 Clock.schedule_once(lambda dt: instance_tabs.switch_tab("Tab 0", search_by="title"), 0) Example().run()
内容的提问来源于stack exchange,提问作者xie186
相关产品推荐
相关产品推荐

