You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Kivy/KivyMD中如何实现需先点击首标签按钮才可切换其他标签

问题原因

  • on_tab_switch 是标签切换动作触发、切换动画执行过程中才回调的事件,此时直接调用 switch_tab 会和正在进行的切换流程冲突,导致跳回操作被拦截,必须等当前动画结束后第二次点击才能生效。

修复方法

通过 Kivy 时钟调度把跳回 Tab 0 的操作延迟到下一帧执行,避开当前切换流程的冲突即可,修改点如下:

  1. 导入 Kivy 时钟模块:from kivy.clock import Clock
  2. 修改 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 01:36:02