Kivy - FloatLayout 中的定时器集成
Kivy - Timer Integration in FloatLayout
问题很简单,让 Kivy 将 Timer1 代码作为标签集成到 FloatLayout。
我有这个 .py 文件:
import kivy
kivy.require('1.10.0')
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen, FadeTransition
from kivy.app import App
from kivy.uix.label import Label
from kivy.uix.image import Image
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.stacklayout import StackLayout
from kivy.clock import Clock
from kivy.properties import StringProperty, NumericProperty, ObjectProperty
from digitalclock import DigitalClock
from kivy.animation import Animation
import time
class IntroScreen(Screen):
pass
class ContScreen(Screen):
pass
class ScreenManagement(ScreenManager):
pass
backbone = Builder.load_file("main.kv")
class Status(FloatLayout):
_change = StringProperty()
_tnd = ObjectProperty(None)
def update(self, *args):
self.time = time.asctime()
self._change = str(self.time)
self._tnd.text = str(self.time)
print (self._change)
class Timer1(Label):
a = NumericProperty(10) # seconds
color = 1, 1, 1, 1
font_size = 50
def start(self):
Animation.cancel_all(self) # stop any current animations
self.anim = Animation(a=0, duration=self.a)
def finish_callback(animation, incr_crude_clock):
incr_crude_clock.text = "COOL"
self.anim.bind(on_complete=finish_callback)
self.anim.start(self)
def on_a(self, instance, value):
self.text = str(round(value, 1))
class XGApp(App):
time = StringProperty()
def update(self, *args):
self.time = str(time.asctime())
def build (self):
Clock.schedule_interval(self.update, 1)
t1 = Timer1()
return backbone
xApp = XGApp()
if __name__ == "__main__":
xApp.run()
和.kv:
<ContScreen>:
DigitalClock:
pos_hint: {'center_x': 0.1, 'center_y': 0.9}
size_hint: (0.075, 0.075)
StackLayout
orientation: "tb-rl"
spacing: 15
Button:
text: "1"
size_hint: None, .16
width: 225
on_press:
self.background_color = (1.7, 0, 1.7, 1)
t1.start()
我正在尝试将 Timer1 方面作为 .kv 上 FloatLayout 中的标签,它在触发按钮时出现。目前,我得到的是作为全屏标签的 Timer1。
请帮忙!
使其工作的一种方法是让 Button
创建计时器。首先将 start_timer()
方法添加到 ContScreen
class:
class ContScreen(Screen):
def start_timer(self, *args):
timer = Timer1(size_hint=(0.2, 0.2))
self.add_widget(timer)
timer.start()
要使其生效,请进行其他三项更改:
- 更改您的
main.kv
文件以制作根小部件(消除 ContScreen
周围的 <>
)。
- 更改
.kv
文件中按钮的 on_press
,将 t1.start()
替换为 root.start_timer()
。
- 从
XGApp
class 中的 build
方法中删除 t1 = Timer1()
语句。
另一种方法是在 .kv
文件中创建 Timer1
,然后在按下 Button
时启动它 运行。为此,请更改您的 .kv
文件以包含 Timer
:
ContScreen:
DigitalClock:
pos_hint: {'center_x': 0.1, 'center_y': 0.9}
size_hint: (0.075, 0.075)
StackLayout
orientation: "tb-rl"
spacing: 15
Button:
text: "1"
size_hint: None, .16
width: 225
on_press:
self.background_color = (1.7, 0, 1.7, 1)
timer.start()
Timer1:
id: timer
text: '0.0'
size_hint: (0.2, 0.2)
将您的 backbone = Builder.load_file("main.kv")
移动到 Timer1
class 的定义之后。并将 ContScreen
class 改回:
class ContScreen(Screen):
pass
解决方案
- 将定时器标签的设计视图从 Python 代码移动到 kv 文件中。
- 为classTimer添加构造函数并接受参数,
root, instance, duration, bg_colour
- 在kv文件中,实例化Timer[=38时传递参数root(屏幕'cont')、按钮实例、持续时间、背景颜色 =]
- 在 build 方法中,删除
t1 = Timer1()
例子
main.py
import kivy
kivy.require('1.11.0')
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.label import Label
from kivy.uix.floatlayout import FloatLayout
from kivy.clock import Clock
from kivy.properties import StringProperty, NumericProperty, ObjectProperty
from kivy.animation import Animation
import time
class IntroScreen(Screen):
pass
class ContScreen(Screen):
pass
class ScreenManagement(ScreenManager):
pass
class Status(FloatLayout):
_change = StringProperty()
_tnd = ObjectProperty(None)
def update(self, *args):
self.time = time.asctime()
self._change = str(self.time)
self._tnd.text = str(self.time)
print (self._change)
class Timer(Label):
a = NumericProperty() # seconds
def __init__(self, root, instance, duration, bg_colour, **kwargs):
super(Timer, self).__init__(**kwargs)
self.obj = instance
self.a = duration
self.root = root
self.obj.disabled = True # disable widget/button
self.obj.background_color = bg_colour
self.root.add_widget(self) # add Timer/Label widget to screen, 'cont'
def animation_complete(self, animation, widget):
self.root.remove_widget(widget) # remove Timer/Label widget to screen, 'cont'
self.obj.background_color = [1, 1, 1, 1] # reset to default colour
self.obj.disabled = False # enable widget/button
def start(self):
Animation.cancel_all(self) # stop any current animations
self.anim = Animation(a=0, duration=self.a)
self.anim.bind(on_complete=self.animation_complete)
self.anim.start(self)
def on_a(self, instance, value):
self.text = str(round(value, 1))
class XGApp(App):
time = StringProperty()
def update(self, *args):
self.time = str(time.asctime())
def build (self):
Clock.schedule_interval(self.update, 1)
return Builder.load_file("main.kv")
if __name__ == "__main__":
XGApp().run()
kv文件
#:import DigitalClock digitalclock
#:import Timer main.Timer
<ContScreen>:
DigitalClock:
pos_hint: {'center_x': 0.1, 'center_y': 0.9}
size_hint: (0.075, 0.075)
StackLayout
orientation: "tb-rl"
spacing: 15
Button:
text: "1"
size_hint: None, .16
width: 225
on_press:
Timer(root, self, 5, [0.17, 1.7, 0, 1]).start()
Button:
text: "2"
size_hint: None, .16
width: 225
on_press:
Timer(root, self, 10, [1.7, 0, 1.7, 1]).start()
<Timer>:
canvas.before:
Color:
rgba: 0, 0, 0.5, 1 # 50% blue
Rectangle:
size: self.size
pos: self.pos
size_hint: 0.3, .1
font_size: 50
pos_hint: {'center_x': 0.5, 'center_y': 0.5}
输出
问题很简单,让 Kivy 将 Timer1 代码作为标签集成到 FloatLayout。
我有这个 .py 文件:
import kivy
kivy.require('1.10.0')
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen, FadeTransition
from kivy.app import App
from kivy.uix.label import Label
from kivy.uix.image import Image
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.stacklayout import StackLayout
from kivy.clock import Clock
from kivy.properties import StringProperty, NumericProperty, ObjectProperty
from digitalclock import DigitalClock
from kivy.animation import Animation
import time
class IntroScreen(Screen):
pass
class ContScreen(Screen):
pass
class ScreenManagement(ScreenManager):
pass
backbone = Builder.load_file("main.kv")
class Status(FloatLayout):
_change = StringProperty()
_tnd = ObjectProperty(None)
def update(self, *args):
self.time = time.asctime()
self._change = str(self.time)
self._tnd.text = str(self.time)
print (self._change)
class Timer1(Label):
a = NumericProperty(10) # seconds
color = 1, 1, 1, 1
font_size = 50
def start(self):
Animation.cancel_all(self) # stop any current animations
self.anim = Animation(a=0, duration=self.a)
def finish_callback(animation, incr_crude_clock):
incr_crude_clock.text = "COOL"
self.anim.bind(on_complete=finish_callback)
self.anim.start(self)
def on_a(self, instance, value):
self.text = str(round(value, 1))
class XGApp(App):
time = StringProperty()
def update(self, *args):
self.time = str(time.asctime())
def build (self):
Clock.schedule_interval(self.update, 1)
t1 = Timer1()
return backbone
xApp = XGApp()
if __name__ == "__main__":
xApp.run()
和.kv:
<ContScreen>:
DigitalClock:
pos_hint: {'center_x': 0.1, 'center_y': 0.9}
size_hint: (0.075, 0.075)
StackLayout
orientation: "tb-rl"
spacing: 15
Button:
text: "1"
size_hint: None, .16
width: 225
on_press:
self.background_color = (1.7, 0, 1.7, 1)
t1.start()
我正在尝试将 Timer1 方面作为 .kv 上 FloatLayout 中的标签,它在触发按钮时出现。目前,我得到的是作为全屏标签的 Timer1。
请帮忙!
使其工作的一种方法是让 Button
创建计时器。首先将 start_timer()
方法添加到 ContScreen
class:
class ContScreen(Screen):
def start_timer(self, *args):
timer = Timer1(size_hint=(0.2, 0.2))
self.add_widget(timer)
timer.start()
要使其生效,请进行其他三项更改:
- 更改您的
main.kv
文件以制作根小部件(消除ContScreen
周围的<>
)。 - 更改
.kv
文件中按钮的on_press
,将t1.start()
替换为root.start_timer()
。 - 从
XGApp
class 中的build
方法中删除t1 = Timer1()
语句。
另一种方法是在 .kv
文件中创建 Timer1
,然后在按下 Button
时启动它 运行。为此,请更改您的 .kv
文件以包含 Timer
:
ContScreen:
DigitalClock:
pos_hint: {'center_x': 0.1, 'center_y': 0.9}
size_hint: (0.075, 0.075)
StackLayout
orientation: "tb-rl"
spacing: 15
Button:
text: "1"
size_hint: None, .16
width: 225
on_press:
self.background_color = (1.7, 0, 1.7, 1)
timer.start()
Timer1:
id: timer
text: '0.0'
size_hint: (0.2, 0.2)
将您的 backbone = Builder.load_file("main.kv")
移动到 Timer1
class 的定义之后。并将 ContScreen
class 改回:
class ContScreen(Screen):
pass
解决方案
- 将定时器标签的设计视图从 Python 代码移动到 kv 文件中。
- 为classTimer添加构造函数并接受参数,
root, instance, duration, bg_colour
- 在kv文件中,实例化Timer[=38时传递参数root(屏幕'cont')、按钮实例、持续时间、背景颜色 =]
- 在 build 方法中,删除
t1 = Timer1()
例子
main.py
import kivy
kivy.require('1.11.0')
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.label import Label
from kivy.uix.floatlayout import FloatLayout
from kivy.clock import Clock
from kivy.properties import StringProperty, NumericProperty, ObjectProperty
from kivy.animation import Animation
import time
class IntroScreen(Screen):
pass
class ContScreen(Screen):
pass
class ScreenManagement(ScreenManager):
pass
class Status(FloatLayout):
_change = StringProperty()
_tnd = ObjectProperty(None)
def update(self, *args):
self.time = time.asctime()
self._change = str(self.time)
self._tnd.text = str(self.time)
print (self._change)
class Timer(Label):
a = NumericProperty() # seconds
def __init__(self, root, instance, duration, bg_colour, **kwargs):
super(Timer, self).__init__(**kwargs)
self.obj = instance
self.a = duration
self.root = root
self.obj.disabled = True # disable widget/button
self.obj.background_color = bg_colour
self.root.add_widget(self) # add Timer/Label widget to screen, 'cont'
def animation_complete(self, animation, widget):
self.root.remove_widget(widget) # remove Timer/Label widget to screen, 'cont'
self.obj.background_color = [1, 1, 1, 1] # reset to default colour
self.obj.disabled = False # enable widget/button
def start(self):
Animation.cancel_all(self) # stop any current animations
self.anim = Animation(a=0, duration=self.a)
self.anim.bind(on_complete=self.animation_complete)
self.anim.start(self)
def on_a(self, instance, value):
self.text = str(round(value, 1))
class XGApp(App):
time = StringProperty()
def update(self, *args):
self.time = str(time.asctime())
def build (self):
Clock.schedule_interval(self.update, 1)
return Builder.load_file("main.kv")
if __name__ == "__main__":
XGApp().run()
kv文件
#:import DigitalClock digitalclock
#:import Timer main.Timer
<ContScreen>:
DigitalClock:
pos_hint: {'center_x': 0.1, 'center_y': 0.9}
size_hint: (0.075, 0.075)
StackLayout
orientation: "tb-rl"
spacing: 15
Button:
text: "1"
size_hint: None, .16
width: 225
on_press:
Timer(root, self, 5, [0.17, 1.7, 0, 1]).start()
Button:
text: "2"
size_hint: None, .16
width: 225
on_press:
Timer(root, self, 10, [1.7, 0, 1.7, 1]).start()
<Timer>:
canvas.before:
Color:
rgba: 0, 0, 0.5, 1 # 50% blue
Rectangle:
size: self.size
pos: self.pos
size_hint: 0.3, .1
font_size: 50
pos_hint: {'center_x': 0.5, 'center_y': 0.5}