如何在Kivy弹出窗口中修改DayWindow屏幕的按钮文本?
问题解决:从Popup中修改Screen内按钮文本
问题背景
需要实现:点击弹出窗口中的“Schlafen”按钮时,将DayWindow屏幕内对应的“Choose Activity”按钮文本修改为“Schlafen”。但尝试访问DayWindow时出现以下错误:
'super' object has no attribute '__getattr__'Screen "day" does not exist
错误原因
- 直接调用
DayWindow.change_button()是操作类而非运行中的Screen实例,新建ScreenManager()也无法获取已存在的界面元素 - Popup不知道是哪个按钮触发的弹窗,无法定位要修改的目标按钮
change_button定义为无实例参数的方法,不符合Kivy实例方法的要求
修改后的Python代码
from kivy.app import App from kivy.lang import Builder from kivy.uix.screenmanager import ScreenManager, Screen from kivy.properties import ObjectProperty from kivy.uix.floatlayout import FloatLayout from kivy.uix.popup import Popup from datetime import date, timedelta import json class MenuWindow(Screen): pass class DayWindow(Screen): null = ObjectProperty("Null") def btn(self, target_btn): # 弹窗时传入要修改的目标按钮 show_ActivityPopup(target_btn) class WeekWindow(Screen): pass class MonthWindow(Screen): pass class WindowManager(ScreenManager): pass class ActivityPopup(FloatLayout): def __init__(self, target_btn, **kwargs): super().__init__(**kwargs) self.target_btn = target_btn # 保存要修改的按钮实例 def change_to_schlafen(self): # 修改目标按钮的文本 self.target_btn.text = "Schlafen" def show_ActivityPopup(target_btn): show = ActivityPopup(target_btn) popup_window = Popup(title="Activities", content=show, auto_dismiss=False) popup_window.open() kv = Builder.load_file("my.kv") class MyMainApp(App): def build(self): return kv if __name__ == "__main__": MyMainApp().run()
修改后的kv文件
WindowManager: MenuWindow: DayWindow: WeekWindow: MonthWindow: <MenuWindow>: name: "menu" GridLayout: cols:1 Label: text: "Time/MoodTracker" Button: text: "Day" on_release: app.root.current = "day" root.manager.transition.direction ="left" GridLayout: cols: 2 Button: text: "Weekly Overview" on_release: app.root.current = "week" root.manager.transition.direction ="left" Button: text: "Monthly Overview" on_release: app.root.current = "month" root.manager.transition.direction ="left" <DayWindow>: name: "day" ScrollView: GridLayout: cols: 2 size_hint_y: None height: self.minimum_height # 修复ScrollView内容不滚动的问题 Label: text: "0:00 - 0:30" Button: id: null text: root.null on_release: root.btn(self) # 传递当前按钮实例给弹窗 Label: text: "0:30 - 1:00" Button: text: "Choose Activity" on_release: root.btn(self) Label: text: "1:00 - 1:30" Button: text: "Choose Activity" on_release: root.btn(self) Label: text: "1:30 - 2:00" Button: text: "Choose Activity" on_release: root.btn(self) Label: text: "2:00 - 2:30" Button: text: "Choose Activity" on_release: root.btn(self) <ActivityPopup>: auto_dismiss: False ScrollView: GridLayout: size_hint_y: None cols:1 height: dp(600) spacing: "10dp" Button: text: "Schlafen" on_release: root.change_to_schlafen() root.parent.parent.dismiss() # 简化弹窗关闭逻辑 Button: text: "Frühstücken" on_release: root.parent.parent.dismiss() Button: text: "Kochen" on_release: root.parent.parent.dismiss() Button: text: "Lernen" on_release: root.parent.parent.dismiss() Button: text: "Joggen" on_release: root.parent.parent.dismiss() <WeekWindow>: name: "week" Button: text: "Back" on_release: app.root.current = "menu" root.manager.transition.direction ="right" <MonthWindow>: name: "month" Button: text: "Back" on_release: app.root.current = "menu" root.manager.transition.direction ="right"
关键改动说明
- 传递目标按钮实例:DayWindow的
btn方法接收点击的按钮实例,弹窗时将其传入ActivityPopup,让Popup明确知道要修改哪个按钮 - Popup初始化保存目标:ActivityPopup在
__init__中保存目标按钮,避免全局查找界面元素 - 修复ScrollView布局:给DayWindow的GridLayout添加
size_hint_y: None和height: self.minimum_height,确保内容可滚动 - 简化弹窗关闭逻辑:用
root.parent.parent.dismiss()替代多层嵌套的parent调用,更简洁可靠 - 修正拼写错误:将kv中的"Choose Aviticity"改为"Choose Activity","Weelky"改为"Weekly"
内容的提问来源于stack exchange,提问作者pz_Orbital
相关产品推荐
相关产品推荐

