Kivy:ScreenManager-访问子属性

时间:2019-07-07 16:14:31

标签: python kivy kivy-language

我正在构建一个应用程序,我需要它反复递减计数到零,直到达到时间限制。一切正常,但是我当前的问题是,当它结束时,我希望其中一个标签说“已完成”,并尝试使用ids方法时,由于该应用程序崩溃时,我始终会收到KeyError:'count_down1'消息调用finish_callback()函数结束。

我是kivy的新手,但是我最好的猜测是self.ids []指的是在根窗口小部件(即WindowManager)中定义的ID,但是ID:“ count_down1”在WindowManager的子窗口小部件(即SecondWindow)。但是,即使这是正确的,我也无法找出解决方法,也无法从其他类似问题中提取正确答案。

py文件

from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.animation import Animation
from kivy.properties import NumericProperty
from random import randint


class MainWindow(Screen):
    pass

class SecondWindow(Screen):
    pass


class WindowManager(ScreenManager):
    a = NumericProperty(0)
    b = NumericProperty(0)
    run_t = 5
    min = 3
    max = 7

    def reset(self):
        self.a = 0
        self.b = 0

    def start(self, *args):
        self.a = randint(self.min, self.max)
        self.anim = Animation(a = 0, duration = self.a)
        if self.run_t - self.b <= self.max:
            self.a = self.run_t - self.b
            print("a=", self.a, "b=", self.b)
            self.anim = Animation(a = 0, duration = self.a)
        else:
            print(self.run_t - self.b)
            self.anim.bind(on_complete = self.start)

        self.anim.start(self)

    def count_up(self):
        self.anim = Animation(b = self.run_t, duration = self.run_t)
        self.anim.bind(on_complete = self.finish_callback)
        self.anim.start(self)

    def finish_callback(self, animation, param):
        print('in finish_callback')
        end_1 = self.ids['count_down1']
        end_1.text = 'Finished'
        #^^this is where the error occurs^^


 kv = Builder.load_file("updown.kv")

class PageScrollerApp(App):
    def build(self):
        return kv

if __name__ == "__main__":
    PageScrollerApp().run()

kv文件

WindowManager:
    MainWindow:
    SecondWindow:

<MainWindow>:
    name: "home"

    FloatLayout:        
        Button:
            pos_hint: {"x":0.4, "y":0.05}
            text: "Go!"
            on_release:
                root.manager.reset()
                root.manager.start()
                root.manager.count_up()
                root.manager.current = 'low'

<SecondWindow>:
    name: 'low'

    FloatLayout:        
        Label:            
            id: count_down1
            text: str(round(root.manager.a, 1))
            pos_hint: {"x": 0.4, "y": 0.55}
        Label:           
            id: count_up1
            text: str(round(root.manager.b, 1))
            pos_hint: {"x": 0.4, "y": 0.3}
        Button:
            background_color: 0.5,0.1,1,1
            text: 'Cancel'
            pos_hint: {"x":0.4, "y":0.05}
            on_release:
                root.manager.current = "medium"

<TextInput>
    size_hint: 0.24,0.1
    font_size: 35

<Button>
    font_size: 20
    color:1,0.2,0.5,1
    size_hint: 0.2, 0.1
    background_color: 0.5,0.8,0.2,1

<Label>
    font_size: 20
    color:1,0.2,0.5,1
    size_hint: 0.2, 0.1
    background_color: 0.5,0.2,0.9,1

出于可读性考虑,我尝试删除所有不必要的代码。总而言之,我想我的问题是如何访问和更改子窗口小部件的属性?任何帮助将不胜感激!

1 个答案:

答案 0 :(得分:0)

问题-KeyError

  

在应用程序崩溃时立即收到KeyError:'count_down1'消息   调用finish_callback()函数结束。

根本原因

在屏幕管理器中未定义id: count_down1。它在SecondWindow()中定义,但是ScreenManager无法访问它。

Kv language » Referencing Widgets

id的范围仅限于在其中声明的规则,因此在count_down1规则之外无法访问您的应用<SecondWindow>

解决方案

  1. id: second_window添加到实例化对象SecondWindow:中,以便您可以引用在SecondWindow中声明的所有ID
  2. self.ids[替换] count_down1 self.ids.second_window.ids.count_down1

摘要-kv文件

WindowManager:
    MainWindow:
    SecondWindow:
        id: second_window

代码段-py文件

def finish_callback(self, animation, param):
    print('in finish_callback')
    self.ids.second_window.ids.count_down1.text = 'Finished'