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
相关产品推荐
相关产品推荐

