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

Kivy中通过if条件切换屏幕失效问题求助

问题分析与解决方案

你遇到的问题主要出在Spinner状态的判断逻辑和KV语言的属性引用方式上,下面一步步帮你修正:

1. 错误的Spinner state设置

你在KV里给Spinner写的self.state: 'True'是无效的:

  • Spinner控件本身并没有你自定义的state属性,这样设置不会生效
  • 你想要判断Spinner是否选中了有效选项,其实直接判断它的text是否不是初始提示文本(比如"Day"、"Hour")就可以,不需要额外维护state

2. KV里的属性引用错误

在KV中,要访问Screen里的子控件属性,必须通过root.ids.控件id的方式,你直接写day.state是找不到这个控件的,而且也没有这个属性。

3. 修正后的代码改动

第一步:修改ScreenTwo的KV代码

把按钮的on_press逻辑改成直接判断每个Spinner的text是否为有效选项:

Button:
    background_color: 0, 0, 0, 1
    size: (400, 130)
    size_hint: (None, None)
    pos_hint: {'right': 0.6, 'center_y': 0}
    on_press:
        root.hours_checking()
        # 判断所有Spinner都选中了非初始值
        if (root.ids.day.text != 'Day' and 
            root.ids.hours.text != 'Hour' and 
            root.ids.minutes.text != 'Minutes' and 
            root.ids.AmPm.text != 'AM/PM'):
            root.manager.current = 'screen_three'

同时删除所有Spinner里的self.state: 'True'这行代码,因为完全没必要。

第二步:修正ScreenTwo类的错误

你的__init__方法里的self.state = state会报错,因为state变量未定义,直接删掉这行;另外尽量避免使用全局变量,改用实例属性存储选中的值,更清晰:

class ScreenTwo(Screen):
    def __init__(self, **kwargs):
        super(ScreenTwo, self).__init__(**kwargs)
        # 用实例属性存储选中值,替代全局变量
        self.day = ""
        self.hours = 0
        self.minutes = 0
        self.AmPm = ""

    def time_now(self):
        # 这里的变量不需要全局,用局部变量即可
        now = datetime.now()
        print(now)
        month_now = int(now.strftime("%m")) # month in int
        print("month:", month_now)
        date_now = int(now.strftime("%d")) # date in int
        print("date:", date_now)
        day_now = now.strftime("%A") # day in str
        print("day of the week:", day_now)
        hour_now = int(now.strftime("%H")) * 100
        minute_now = int(now.strftime("%M"))
        time_now = hour_now + minute_now # day in str in 24 hour format
        print("time:", time_now)

    def check_open(self, day_now, opening_days, time_now, opening_time):
        # 这里也改成实例方法,去掉global
        isopen = False
        opening_days = ["Monday", "Tuesday", "Wednesday", "Thursday", "Saturday"]
        opening_time = [800, 2200]
        if day_now in opening_days and time_now >= opening_time[0] and time_now <= opening_time[1]:
            isopen = True
            print("Is the store open? ", isopen)
            return isopen
        else:
            print("Is the store open? ", isopen)
            return isopen

    def on_day_select(self, text):
        self.day = str(text)

    def on_hours_select(self, text):
        self.hours = int(text)

    def on_minutes_select(self, text):
        self.minutes = int(text)

    def on_AmPm_select(self,text):
        self.AmPm = str(text)

    def hours_checking(self):
        try:
            if 1 <= self.hours <= 11 and self.AmPm == 'a.m':
                pass
            elif 1 <= self.hours <= 12 and self.AmPm == 'p.m':
                self.hours += 12
            elif self.hours == 12 and self.AmPm == 'a.m':
                self.hours = 0
        except Exception as e:
            print(f'error: {e}')
        else:
            print(self.day, self.hours, self.minutes)

第三步:其他小修正

  • check_open方法原来没有self参数,改成实例方法加上self
  • 异常捕获里加上具体的错误信息,方便调试
  • 去掉所有不必要的global声明,改用实例属性管理状态

为什么这样改能解决问题?

  • 直接通过Spinner的text判断是否选中有效选项,逻辑更直观,也不需要维护额外的state属性
  • 在KV里通过root.ids.xxx正确访问到Screen里的Spinner控件,确保判断逻辑能获取到正确的控件状态
  • 用实例属性替代全局变量,代码更清晰,也避免了全局变量可能带来的意外问题

现在你运行代码,当四个Spinner都选中了非初始的选项后,点击按钮就能正常跳转到screen_three了。

内容的提问来源于stack exchange,提问作者Kushal Sai Gunturi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:42:18