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

如何在Kivy弹出窗口中修改DayWindow屏幕的按钮文本?

问题解决:从Popup中修改Screen内按钮文本

问题背景

需要实现:点击弹出窗口中的“Schlafen”按钮时,将DayWindow屏幕内对应的“Choose Activity”按钮文本修改为“Schlafen”。但尝试访问DayWindow时出现以下错误:

  • 'super' object has no attribute '__getattr__'
  • Screen "day" does not exist

错误原因

  1. 直接调用DayWindow.change_button()是操作类而非运行中的Screen实例,新建ScreenManager()也无法获取已存在的界面元素
  2. Popup不知道是哪个按钮触发的弹窗,无法定位要修改的目标按钮
  3. 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"

关键改动说明

  1. 传递目标按钮实例:DayWindow的btn方法接收点击的按钮实例,弹窗时将其传入ActivityPopup,让Popup明确知道要修改哪个按钮
  2. Popup初始化保存目标:ActivityPopup在__init__中保存目标按钮,避免全局查找界面元素
  3. 修复ScrollView布局:给DayWindow的GridLayout添加size_hint_y: None和height: self.minimum_height,确保内容可滚动
  4. 简化弹窗关闭逻辑:用root.parent.parent.dismiss()替代多层嵌套的parent调用,更简洁可靠
  5. 修正拼写错误:将kv中的"Choose Aviticity"改为"Choose Activity","Weelky"改为"Weekly"

内容的提问来源于stack exchange,提问作者pz_Orbital

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 15:24:08