为什么我的代码出现Kivy KeyError :?

时间:2019-10-31 16:30:38

标签: python python-3.x kivy kivy-language

我正在尝试创建一个简单的登录名,并在下一个屏幕中显示当前时间,但我只是不明白为什么我一直收到此错误。

*。py文件

from kivy.app import App
from datetime import datetime
from datetime import timedelta
from kivy.clock import Clock
from kivy.uix.label import Label
from kivy.uix.boxlayout import BoxLayout
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen


class test(BoxLayout):
    pass

class blank_page(Screen):
    pass

class ScreenManagement(ScreenManager):
    pass

kv = Builder.load_file("delete.kv")
class MyApp(App):
    def build(self):

        self.now = datetime.now()
        Clock.schedule_interval(self.update_clock, 1)
        self.my_label = Label(text= self.now.strftime('%H:%M:%S'))
        return kv

    def update_clock(self, *args):
        self.now = self.now + timedelta(seconds = 1)
        self.root.ids['my_label'].text = self.now.strftime('%H:%M:%S')
        print(self.now.strftime('%H:%M:%S'))

MyApp().run()

*。kv文件


#:kivy 1.0
#:import hex kivy.utils.get_color_from_hex
ScreenManagement:
    test:
    blank_page:
<test>:
    BoxLayout:
        orintation: 'vertical'
        Label:
            text: 'test_label'
<blank_page>:
    BoxLayout:
        orientation:'vertical'
        Label:
            id: my_label
        Button:
            text:'next'
            on_release: app.root.current = "blank_page"

我想要发生的是能够登录,单击将我带到第二个屏幕的按钮,该屏幕将显示时间。但是我一直收到以下错误:

File "kivy\_clock.pyx", line 384, in kivy._clock.CyClockBase._process_events
   File "kivy\_clock.pyx", line 414, in kivy._clock.CyClockBase._process_events
   File "kivy\_clock.pyx", line 412, in kivy._clock.CyClockBase._process_events
   File "kivy\_clock.pyx", line 167, in kivy._clock.ClockEvent.tick
   File "c:/Users/QQQ/Documents/University work/test.py", line 31, in update_clock
     self.root.ids['my_label'].text = self.now.strftime('%H:%M:%S')
 KeyError: 'my_label'

2 个答案:

答案 0 :(得分:0)

这是因为my_label不是您的根的ID,而是blank_page
您可以通过引用blank_page来解决此问题。
我会做这样的事情。
blank_page设为根的对象属性。

KV:

ScreenManagement:
    bp: bp
    test:
    blank_page:
        id: bp
<test>:
    BoxLayout:
        orintation: 'vertical'
        Label:
            text: 'test_label'
<blank_page>:
    BoxLayout:
        orientation:'vertical'
        Label:
            id: my_label
        Button:
            text:'next'
            on_release: app.root.current = "blank_page"

然后,您可以访问该属性的ID。

Python:

class MyApp(App):

    def build(self):

        self.now = datetime.now()
        Clock.schedule_interval(self.update_clock, 1)
        self.my_label = Label(text= self.now.strftime('%H:%M:%S'))
        return kv

    def update_clock(self, *args):
        self.now = self.now + timedelta(seconds = 1)
        self.root.bp.ids['my_label'].text = self.now.strftime('%H:%M:%S')
        print(self.now.strftime('%H:%M:%S'))

答案 1 :(得分:0)

the docs指出:

  

参考小部件

     

在小部件树中,通常需要访问/引用其他   小部件。 Kv语言提供了一种使用ID的方法。认为   它们作为只能在Kv中使用的类级别变量   语言。请考虑以下内容:

<MyFirstWidget>:
    Button:
        id: f_but
    TextInput:
        text: f_but.state

<MySecondWidget>:
    Button:
        id: s_but
    TextInput:
        text: s_but.state
     

ID的范围仅限于声明它的规则,因此在   s_之上的代码,但无法在外部访问   规则。

     

...

强调我的

换句话说,只能通过blank_page访问id my_label。在这种情况下,如果root是ScreenManager,则我们将名称设置为blank_page以便可以访问它。

您还存在以下错误:

  • ScreenManager的子级必须是Screen,在您的情况下测试中是BoxLayout,因此必须将其放置在另一个Screen中或将其删除。

  • 在kv中使用的类的名称必须大写。

  • 在build方法中创建的
  • self.my_label与.kv中创建的

  • self.my_label不同,因此这是不必要的。

考虑到上述情况,解决方案是:

from kivy.app import App
from datetime import datetime
from datetime import timedelta
from kivy.clock import Clock
from kivy.lang import Builder
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.screenmanager import ScreenManager, Screen


class Test(BoxLayout):
    pass


class Blank_Page(Screen):
    pass


class ScreenManagement(ScreenManager):
    pass


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


class MyApp(App):
    def build(self):
        self.now = datetime.now()
        Clock.schedule_interval(self.update_clock, 1)
        return kv

    def update_clock(self, *args):
        self.now = self.now + timedelta(seconds=1)
        self.root.get_screen("blank_page").ids["my_label"].text = self.now.strftime(
            "%H:%M:%S"
        )
        print(self.now.strftime("%H:%M:%S"))


if __name__ == "__main__":
    MyApp().run()
#:kivy 1.0
#:import hex kivy.utils.get_color_from_hex


ScreenManagement:
    Blank_Page:
        name: "blank_page"
    Screen:
        name: "next_page"
        Test:

<Test>:
    BoxLayout:
        orientation: 'vertical'
        Label:
            text: 'test_label'

<blank_page>:
    BoxLayout:
        orientation:'vertical'
        Label:
            id: my_label
        Button:
            text:'next'
            on_release: app.root.current = "next_page"