Почему я получаю Kivy KeyError: с моим кодом? - PullRequest
1 голос
/ 31 октября 2019

Я пытаюсь создать простой логин и на следующем экране показать текущее время, но я просто не понимаю, почему я продолжаю получать эту ошибку.

*. 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 голосов
/ 31 октября 2019

Как указано в документах :

Ссылки на виджеты

В дереве виджетов часто возникает необходимость доступа к другим виджетам или ссылки на них. Язык Kv предоставляет способ сделать это с помощью идентификаторов. Думайте о них как о переменных уровня класса, которые могут использоваться только в языке Kv. Обратите внимание на следующее:

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

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

Идентификатор ограничен в области действия правилом, в котором он объявлен, поэтому в коде выше s_but нельзя получить доступ вне правила .

...

выделение шахты

Другими словами, идентификатор my_label доступен только через blank_page. В этом случае, когда root является ScreenManager, мы затем устанавливаем имя пустым_страницей, чтобы к нему можно было получить доступ.

У вас также есть следующие ошибки:

  • дочерние элементы ScreenManager должны быть Screen, в вашем случае test - это BoxLayout, поэтому вы должны поместить его в другой экран или удалить его.

  • Имена классов, которые используются в kv, должны быть

  • self.my_label, созданный в методе сборки, отличается от созданного в .kv, поэтому в этом нет необходимости.

Учитываявыше, решение:

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"
0 голосов
/ 31 октября 2019

Это потому, что my_label не является идентификатором вашего корня, но blank_page
Вы можете исправить это, сославшись на blank_page.
Я бы сделал что-то подобное.
Makeblank_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"

Затем вы можете получить доступ к идентификаторам этого свойства.

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'))
...