我正在编写一个应用程序,其中我遇到了一种情况,我希望通过迭代for循环来依次为一系列对象设置动画。
当我运行应用程序并单击按钮时,我希望第一个标签文本缩小,等待1.5秒暂停,第二个标签缩小,等待,缩小,等待,缩小等。但是当它运行时,尽管应用程序在1.5秒的每一秒中都会休眠,但直到for循环运行它之后才会发生任何动画,然后它们都会立即运行。
我已从下面的主要代码中删除了问题代码,问题仍然存在。有没有人有解决方案或替代方案?我怀疑它与多线程有关,但这只是猜测。我尝试用@mainthread装饰 shrinkray ,但它似乎没有什么区别。
from kivy.app import App
from kivy.uix.gridlayout import GridLayout
from kivy.uix.label import Label
from kivy.animation import Animation
from kivy.uix.button import Button
import time
class Test(GridLayout):
def __init__(self, **kwargs):
super(Test, self).__init__(**kwargs)
self.cols = 2
self.thislabel1 = Label(text="One")
self.add_widget(self.thislabel1)
self.thislabel2 = Label(text="Two")
self.add_widget(self.thislabel2)
self.thislabel3 = Label(text="Three")
self.add_widget(self.thislabel3)
self.thislabel4 = Label(text="Four")
self.add_widget(self.thislabel4)
self.thislabel5 = Label(text='Five')
self.add_widget(self.thislabel5)
self.button1 = Button(text='Shrink Ray')
self.button1.bind(on_release=self.shrinkray)
self.add_widget(self.button1)
self.these_children = [self.thislabel1,self.thislabel2,self.thislabel3,self.thislabel4,self.thislabel5]
def shrinkray(self,*args):
anim = Animation(font_size=1)
for these_labels in self.these_children:
anim.start(these_labels)
time.sleep(1.5)
class MyApp(App):
def build(self):
return Test()
if __name__ == '__main__':
MyApp().run()
答案 0 :(得分:0)
你是对的,你需要多线程。因为当你在主线程中循环并使用time.sleep()
时,你的主要kivy循环会受到影响。但是,对于您的示例,您只需要一个额外的thread
来运行循环,如下所示(按照注释):
from kivy.app import App
from kivy.uix.gridlayout import GridLayout
from kivy.uix.label import Label
from kivy.animation import Animation
from kivy.uix.button import Button
import time
import threading
class Test(GridLayout):
def __init__(self, **kwargs):
super(Test, self).__init__(**kwargs)
self.cols = 2
self.thislabel1 = Label(text="One")
self.add_widget(self.thislabel1)
self.thislabel2 = Label(text="Two")
self.add_widget(self.thislabel2)
self.thislabel3 = Label(text="Three")
self.add_widget(self.thislabel3)
self.thislabel4 = Label(text="Four")
self.add_widget(self.thislabel4)
self.thislabel5 = Label(text='Five')
self.add_widget(self.thislabel5)
self.button1 = Button(text='Shrink Ray')
self.button1.bind(on_release=self.shrinkstart) # here the button targets the thread starter function
self.add_widget(self.button1)
self.these_children = [self.thislabel1,self.thislabel2,self.thislabel3,self.thislabel4,self.thislabel5]
def shrinkstart(self, *args):
t = threading.Thread(target=self.shrinkray) # initiate the thread
t.daemon = True # daemon thread so it terminates when stopping the main thread
t.start()
def shrinkray(self):
anim = Animation(font_size=1)
for these_labels in self.these_children:
anim.start(these_labels)
time.sleep(1.5)
class MyApp(App):
def build(self):
return Test()
if __name__ == '__main__':
MyApp().run()