我正在尝试使用 Kivy 推迟活动。更具体地说,我想在屏幕上显示一个文本标签,然后在N秒后将其删除。 到目前为止,我知道time.sleep
不会做这项工作。相反,我尝试创建一个单独的函数(称为eraser()
)来删除屏幕上的任何内容,然后使用Clock.schedule_once(eraser, n)
调用它。
这是我到目前为止所拥有的:
class myLayout(FloatLayout):
def eraser(self):
self.canvas.clear()
def _keyboard_on_key_down(self, keyboard, keycode, text, modifiers):
self.canvas.clear()
global i
i = i + 1
initialy = 400-(stim_list[i]/2)
xlab = Label(text='X', pos=(0, 350))
with self.canvas:
self.add_widget(xlab)
Color(1., 1, 1)
Rectangle(pos=(initialx, initialy), size=(stimwidth, stim_list[i]))
Clock.schedule_once(eraser(),3)
这并没有真正起作用,如果有人能想到正确/更好的方法来做到这一点,我将不胜感激。
Widget
和Canvas
是完全不同的东西,因此仅清洁画布显然不会删除小部件本身,最终使用这种技术,FloatLayout
将有很多Label
小部件作为孩子而不实际删除它们 - 如果你想:),可以称之为泄漏
Widget 使用add_widget()
、remove_widget()
和clear_widgets()
调用,每个调用都超出了with <canvas>
块,尽管是的,如果您确实需要它以这种方式运行,它甚至可以以这种方式工作。
另一方面,Clock.schedule_once()
调用使用您传递给它的函数/方法,在您的情况下,它只是一个返回值eraser()
(这是None
),并在您用括号编写它的同一位置执行函数(eraser()
→调用,eraser
→只是一个函数)。
因此:
- 使用
add_widget()
、remove_widget()
和clear_widgets()
- 除非必要,否则不要将它们放入
with <canvas>
块中(大多数情况下不是!
- 除非必要,否则不要将它们放入
- 将函数/方法作为参数传递,而不是它们的返回值(不要使用括号)
例:
from kivy.clock import Clock
from kivy.lang import Builder
from kivy.uix.label import Label
from kivy.base import runTouchApp
from kivy.uix.floatlayout import FloatLayout
Builder.load_string('''
<Test>:
Button:
size_hint: None, None
on_release: root.test()
''')
class Test(FloatLayout):
def eraser(self, *args):
self.clear_widgets()
def test(self, *args):
lab = Label(text='Hello world!')
self.add_widget(lab)
Clock.schedule_once(self.eraser, 3)
runTouchApp(Test())