Вопрос 2
self.get_screen (self.current) .ids.navtray.ids.label_timer.text =
"{0: .2f} секунд" .format (self.number)
Файл "kivy / properties.pyx", строка 843, в
kivy.properties.ObservableDict. GetAttr
AttributeError: у объекта 'super' нет атрибута ' getattr '
первопричина
Трассировка Python показала следующую ошибку перед AttributeError:
Traceback (последний вызов был последним):
Файл "kivy / properties.pyx", строка 840, в
kivy.properties.ObservableDict. GetAttr
KeyError: 'navtray'
Во время обработки вышеуказанного исключения произошло другое исключение:
self.current
- это имя отображаемого в данный момент экрана или отображаемого экрана.
Когда приложение запускается, отображается первый экран BigScreen
, и на этом экране нет id
с именем navtray
. Из-за отсутствия id: navtray приложение сначала выдало KeyError , а затем AttributeError .
Решение
Существует два решения проблемы.
Метод 1
1) В файле kv добавить вызов метода start()
после вызова метода new_page()
обрывки
Button:
text: 'Lets Begin'
font_size: 24
on_press: app.root.new_page()
on_press: app.root.start()
2) В скрипте Python удалите конструктор __init__()
из class MyScreenManager()
и dt=0
из метода start()
обрывки
class MyScreenManager(ScreenManager):
number = NumericProperty(0)
def increment_time(self, dt):
self.number += .01
self.get_screen(self.current).ids.navtray.ids.label_timer.text = "{0:.2f} secs".format(self.number)
def start(self):
self.timer = Clock.schedule_interval(self.increment_time, .01)
Метод 2
Добавьте if заявление для проверки self.current
.
Отрывки
def increment_time(self, interval):
self.number += .01
if self.current == 'begin':
self.get_screen('start').ids.navtray.ids.label_timer.text = "{0:.2f} secs".format(self.number)
else:
self.get_screen(self.current).ids.navtray.ids.label_timer.text = "{0:.2f} secs".format(self.number)
Вопрос 1
Хотите, чтобы таймер работал непрерывно через несколько экранов
Решение
- Переместить атрибут класса и все методы, определенные в
class NavTray1
, в class MyScreenManager
- Обновите текст
Label
в NavTray1
экземпляре из метода increment_time
, используя self.get_screen(self.current).ids.navtray.ids.label_timer.text = "{0:.2f} secs".format(self.number)
. Мы используем self.current
, потому что, нажимая кнопку Forward
, мы создали новые экземпляры Screen1
и NavTray1
.
Отрывки
файл kv
BoxLayout:
orientation: 'vertical'
size_hint: (.33, 1.0)
id: custom
Label:
id: label_timer
Button:
id: submit_button
py файл
class NavTray1(BoxLayout):
pass
...
class MyScreenManager(ScreenManager):
number = NumericProperty(0)
def __init__(self, **kwargs):
super(MyScreenManager, self).__init__(**kwargs)
Clock.schedule_once(lambda dt: self.start(), 0.5)
def increment_time(self, interval):
self.number += .01
self.get_screen(self.current).ids.navtray.ids.label_timer.text = "{0:.2f} secs".format(self.number)
def start(self):
self.timer = Clock.schedule_interval(self.increment_time, .01)
def stop(self):
Clock.unschedule(self.timer)
print(f"timer={self.number}")
Пример
main.py
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.clock import Clock
from kivy.properties import NumericProperty
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.gridlayout import GridLayout
import time
class SubjectsLayout(GridLayout):
pass
class NavTray1(BoxLayout):
pass
class Screen1(Screen):
pass
class MyScreenManager(ScreenManager):
number = NumericProperty(0)
def __init__(self, **kwargs):
super(MyScreenManager, self).__init__(**kwargs)
Clock.schedule_once(lambda dt: self.start(), 0.5)
def increment_time(self, interval):
self.number += .01
self.get_screen(self.current).ids.navtray.ids.label_timer.text = "{0:.2f} secs".format(self.number)
def start(self):
self.timer = Clock.schedule_interval(self.increment_time, .01)
def stop(self):
Clock.unschedule(self.timer)
print(f"timer={self.number}")
def new_page(self):
name = str(time.time())
s = Screen1(name=name)
self.add_widget(s)
self.current = name
Login = Builder.load_file("main.kv")
class MyApp(App):
def build(self):
return Login
if __name__ == "__main__":
MyApp().run()
main.kv
#:kivy 1.11.0
#:import FadeTransition kivy.uix.screenmanager.FadeTransition
#:import ScrollEffect kivy.effects.scroll.ScrollEffect
#:import SlideTransition kivy.uix.screenmanager.SlideTransition
MyScreenManager:
transition: FadeTransition()
Screen1:
<NavTray1>:
orientation: 'horizontal'
padding: '5dp'
spacing: '5dp'
canvas.before:
Color:
rgb: .1, .1, .1
Rectangle:
size: self.size
pos: self.pos
Button:
color: [0.4, 0.4, 0.4, 1]
size_hint: (.33, None)
height: '80dp'
text: 'Back'
on_release : app.root.transition = SlideTransition(direction='right')
on_release : app.root.current = app.root.previous()
BoxLayout:
orientation: 'vertical'
size_hint: (.33, 1.0)
id: custom
Label:
id: label_timer
Button:
id: submit_button
color: [6/255, 114/255, 0, 1]
size_hint: (.33, None)
height: '80dp'
text: 'Forward'
background_color: [28/138, 1, 35/138, 0.5]
on_release : app.root.new_page()
on_release : app.root.transition = SlideTransition(direction='left')
<Screen1>:
name: "start"
BoxLayout:
orientation: 'vertical'
size: root.size
pos: root.pos
id: box
ScrollView:
size_hint: (1.0, None)
height: root.height - navtray.height
SubjectsLayout:
id: subjects
cols: 1
Label:
text: root.name
NavTray1:
size_hint: (1.0, None)
id: navtray
height: '90dp'
выход
![Kivy ScreenManager - Timer runs continuously across multiple screens](https://i.stack.imgur.com/xDfnL.png)