Kivy:如何 运行 跨多个屏幕使用相同的功能
Kivy: How to run the same function across several screens
我正在尝试制作一个计时器,该计时器从随机起始数字重复倒数到零,直到达到预定的时间限制。我已经设法在一个屏幕上执行此操作,但我无法将其适应多个屏幕。
目前,如果我 运行 PleaseWork(boxLayout) class 中的函数,它会完全按预期运行。但是,我想添加一些屏幕,以便主屏幕有一个显示 "Go!" 的按钮,并且在释放按钮时启动计时器。我希望能够在计时器上的值完全相同的情况下从第二个屏幕循环到第三个屏幕,但我不确定该怎么做。
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 ThirdWindow(Screen):
pass
class WindowManager(ScreenManager):
pass
class PleaseWork(App):
a = NumericProperty(0)
b = NumericProperty(0)
run_t= 15
min = 3
max = 7
def start(self):
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)
print('starting anim number:', self.lap_counter)
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_down']
end_1.text = 'Finished'
Animation.cancel_all(self)
kv = Builder.load_file("integrate.kv")
class PageScrollerApp(App):
def build(self):
return kv
if __name__ == "__main__":
PageScrollerApp().run()
kv 文件:
WindowManager:
MainWindow:
SecondWindow:
ThirdWindow:
<MainWindow>:
name: "home"
FloatLayout:
Button:
pos_hint: {"x":0.4, "y":0.05}
text: "Go!"
on_release:
app.root.current = 'low'
<SecondWindow>:
name: 'low'
FloatLayout:
Label:
id: count_down1
text: str(round(root.a, 1))
pos_hint: {"x": 0.4, "y": 0.55}
Button:
background_color: 0.5,0.1,1,1
text: 'next'
pos_hint: {"x":0.4, "y":0.05}
on_release:
app.root.current = "medium"
<ThirdWindow>:
name: "medium"
FloatLayout:
Label:
id: count_down2
text: str(round(root.a, 1))
pos_hint: {"x": 0.4, "y": 0.55}
Button:
background_color: 0.5,0.1,1,1
text: 'Cancel'
pos_hint: {"x":0.4, "y":0.05}
on_release:
app.root.current = "home"
<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
目前,如果我尝试 运行 该程序,它会出现以下错误消息:
AttributeError: 'SecondWindow' object has no attribute 'a'
但我也意识到我实际上并没有在任何时候调用 PleaseWork(App) class 中的函数。我只是一直无法弄清楚如何。对不起,如果答案很明显,但我是使用 kivy 的新手!
问题 - AttributeError 'a'
AttributeError: 'SecondWindow' object has no attribute 'a'
根本原因
class 属性,a
仅在 class PleaseWork()
中定义,此 class 不是根。根是 class WindowManager()
.
其他问题
- 定义了两个应用程序class
- 缺少属性,
self.lap_counter
self.ids['count_down']
中缺少 kv id: count_down
解决方案
py 和 kv 文件中需要以下增强功能。
py 文件
- 从
class WindowManager()
中删除 pass
,以及 class header、class PleaseWork(App)
- 实施方法
reset()
将 a
和 b
重置为零
- 在方法
start()
中添加 *args
作为参数
片段 - py 文件
class WindowManager(ScreenManager):
a = NumericProperty(0)
b = NumericProperty(0)
run_t = 15
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)
# print('starting anim number:', self.lap_counter)
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_down']
end_1.text = 'Finished'
Animation.cancel_all(self)
class PageScrollerApp(App):
def build(self):
return Builder.load_file("integrate.kv")
kv 文件
- 在 "Go" 按钮的
on_release
事件中调用方法 reset()
和 start()
- 将所有
root.a
替换为 root.manager.a
片段 - kv 文件
<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.current = 'low'
<SecondWindow>:
name: 'low'
FloatLayout:
Label:
id: count_down1
text: str(round(root.manager.timer.a, 1))
pos_hint: {"x": 0.4, "y": 0.55}
Button:
background_color: 0.5,0.1,1,1
text: 'next'
pos_hint: {"x":0.4, "y":0.05}
on_release:
root.manager.current = "medium"
<ThirdWindow>:
name: "medium"
FloatLayout:
Label:
id: count_down2
text: str(round(root.manager.timer.a, 1))
pos_hint: {"x": 0.4, "y": 0.55}
Button:
background_color: 0.5,0.1,1,1
text: 'Cancel'
pos_hint: {"x":0.4, "y":0.05}
on_release:
root.manager.current = "home"
输出
我正在尝试制作一个计时器,该计时器从随机起始数字重复倒数到零,直到达到预定的时间限制。我已经设法在一个屏幕上执行此操作,但我无法将其适应多个屏幕。
目前,如果我 运行 PleaseWork(boxLayout) class 中的函数,它会完全按预期运行。但是,我想添加一些屏幕,以便主屏幕有一个显示 "Go!" 的按钮,并且在释放按钮时启动计时器。我希望能够在计时器上的值完全相同的情况下从第二个屏幕循环到第三个屏幕,但我不确定该怎么做。
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 ThirdWindow(Screen):
pass
class WindowManager(ScreenManager):
pass
class PleaseWork(App):
a = NumericProperty(0)
b = NumericProperty(0)
run_t= 15
min = 3
max = 7
def start(self):
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)
print('starting anim number:', self.lap_counter)
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_down']
end_1.text = 'Finished'
Animation.cancel_all(self)
kv = Builder.load_file("integrate.kv")
class PageScrollerApp(App):
def build(self):
return kv
if __name__ == "__main__":
PageScrollerApp().run()
kv 文件:
WindowManager:
MainWindow:
SecondWindow:
ThirdWindow:
<MainWindow>:
name: "home"
FloatLayout:
Button:
pos_hint: {"x":0.4, "y":0.05}
text: "Go!"
on_release:
app.root.current = 'low'
<SecondWindow>:
name: 'low'
FloatLayout:
Label:
id: count_down1
text: str(round(root.a, 1))
pos_hint: {"x": 0.4, "y": 0.55}
Button:
background_color: 0.5,0.1,1,1
text: 'next'
pos_hint: {"x":0.4, "y":0.05}
on_release:
app.root.current = "medium"
<ThirdWindow>:
name: "medium"
FloatLayout:
Label:
id: count_down2
text: str(round(root.a, 1))
pos_hint: {"x": 0.4, "y": 0.55}
Button:
background_color: 0.5,0.1,1,1
text: 'Cancel'
pos_hint: {"x":0.4, "y":0.05}
on_release:
app.root.current = "home"
<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
目前,如果我尝试 运行 该程序,它会出现以下错误消息:
AttributeError: 'SecondWindow' object has no attribute 'a'
但我也意识到我实际上并没有在任何时候调用 PleaseWork(App) class 中的函数。我只是一直无法弄清楚如何。对不起,如果答案很明显,但我是使用 kivy 的新手!
问题 - AttributeError 'a'
AttributeError: 'SecondWindow' object has no attribute 'a'
根本原因
class 属性,a
仅在 class PleaseWork()
中定义,此 class 不是根。根是 class WindowManager()
.
其他问题
- 定义了两个应用程序class
- 缺少属性,
self.lap_counter
self.ids['count_down']
中缺少 kv
id: count_down
解决方案
py 和 kv 文件中需要以下增强功能。
py 文件
- 从
class WindowManager()
中删除pass
,以及 class header、class PleaseWork(App)
- 实施方法
reset()
将a
和b
重置为零 - 在方法
start()
中添加
*args
作为参数
片段 - py 文件
class WindowManager(ScreenManager):
a = NumericProperty(0)
b = NumericProperty(0)
run_t = 15
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)
# print('starting anim number:', self.lap_counter)
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_down']
end_1.text = 'Finished'
Animation.cancel_all(self)
class PageScrollerApp(App):
def build(self):
return Builder.load_file("integrate.kv")
kv 文件
- 在 "Go" 按钮的
on_release
事件中调用方法reset()
和start()
- 将所有
root.a
替换为root.manager.a
片段 - kv 文件
<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.current = 'low'
<SecondWindow>:
name: 'low'
FloatLayout:
Label:
id: count_down1
text: str(round(root.manager.timer.a, 1))
pos_hint: {"x": 0.4, "y": 0.55}
Button:
background_color: 0.5,0.1,1,1
text: 'next'
pos_hint: {"x":0.4, "y":0.05}
on_release:
root.manager.current = "medium"
<ThirdWindow>:
name: "medium"
FloatLayout:
Label:
id: count_down2
text: str(round(root.manager.timer.a, 1))
pos_hint: {"x": 0.4, "y": 0.55}
Button:
background_color: 0.5,0.1,1,1
text: 'Cancel'
pos_hint: {"x":0.4, "y":0.05}
on_release:
root.manager.current = "home"