Kivy不会在Popup中播放gif,而其他代码正在运行



在我的Kivy应用程序中,我有一个需要很长时间才能完成的函数。我弹出一个通知用户该功能正在运行。我想有一个gif动画,这样用户就知道应用程序没有崩溃。在测试中,gif在弹出窗口中按预期播放,直到我添加了长时间运行的功能,然后只显示一个静止的图像。其他一切都按预期进行(例如,弹出窗口在功能结束时关闭(。

tl;dr

在执行函数时,如何使gif继续在我的kivy应用程序中播放?

代码摘要

我在很大程度上遵循了Dirty Penguin在构建一个简单的进度条或在Kivy中加载动画中的回答提供的代码:

from kivy.app import App
from kivy.uix.popup import Popup
from kivy.properties import ObjectProperty
from kivy.clock import Clock
import time, threading
class RunningPopup(GridLayout):
fpop = None
def set_pop(self, pwin):
self.fpop = pwin
def close(self):
self.fpop.dismiss()
class ExampleApp(App):
def show_popup(self):
self.pop_up = RunningPopup()
self.pop_up.open()
def process_button_click(self):
# Open the pop up
self.show_popup()
# the original code suggested by dirty penguin
# mythread = threading.Thread(target=self.really_long_function)
# mythread.start()
# I've had better luck with the Clock.schedule_once
Clock.schedule_once(self.really_long_function)
def really_long_function(self):
thistime = time.time() 
while thistime + 5 > time.time(): # 5 seconds
time.sleep(1)
# Once the long running task is done, close the pop up.
self.pop_up.dismiss()
if __name__ == "__main__":
ExampleApp().run()

我的KV文件:

<RunningPopup>:
rows: 3
Label:
size_hint_y: 0.2
text: 'Experiments are running ... '
bold: True
color: hex('#0DB14B')
Label:
size_hint_y: 0.2
text: 'Please be patient, this may take time.'
color: hex('#0DB14B')
Image:
size_hint_y: 0.6
id: loading_animation_gif
height: dp(200)
source: './graphics/loading.gif'
center_x: self.parent.center_x
center_y: self.parent.center_y
allow_stretch: True
size_hint_y: None
anim_delay: 0.05
mipmap: True

已尝试

  • 使用线程-这不是并行运行的,长函数运行,然后弹出窗口闪烁打开和关闭
  • 使用kivyclock schedule_one-这似乎效果最好,因为弹出窗口按预期打开和关闭/在长时间运行的功能中
  • 使用图像的Zip文件而不是gif文件(如这里所建议的:gif Animation未在Kivy应用程序中播放(

相关

  • 在Kivy中构建一个简单的进度条或加载动画
  • Gif动画未在Kivy应用程序中播放
  • 尝试在Kivy中播放GIF时使用白色背景

使用Thread即可。以下是使用线程的代码的修改版本。我不得不做一些更改,只是为了让你的代码运行:

from kivy.app import App
from kivy.lang import Builder
from kivy.uix.popup import Popup
import time, threading
kv = '''
#:import hex kivy.utils.get_color_from_hex
Button:
text: 'doit'
on_release: app.process_button_click()

<RunningPopup>:
GridLayout:
rows: 3

Label:
size_hint_y: 0.2
text: 'Experiments are running ... '
bold: True
color: hex('#0DB14B')

Label:
size_hint_y: 0.2
text: 'Please be patient, this may take time.'
color: hex('#0DB14B')

Image:
size_hint_y: 0.6
id: loading_animation_gif
height: dp(200)
source: 'elephant.gif'  # my gif file
center_x: self.parent.center_x
center_y: self.parent.center_y
allow_stretch: True
size_hint_y: None
anim_delay: 0.05
mipmap: True
'''
class RunningPopup(Popup):
fpop = None
def set_pop(self, pwin):
self.fpop = pwin
def close(self):
self.fpop.dismiss()
class ExampleApp(App):
def build(self):
return Builder.load_string(kv)
def show_popup(self):
self.pop_up = RunningPopup()
self.pop_up.open()
def process_button_click(self):
# Open the pop up
self.show_popup()
# the original code suggested by dirty penguin
mythread = threading.Thread(target=self.really_long_function)
mythread.start()
# I've had better luck with the Clock.schedule_once
# Clock.schedule_once(self.really_long_function)
def really_long_function(self, *args):
thistime = time.time()
while thistime + 5 > time.time(): # 5 seconds
time.sleep(1)
# Once the long running task is done, close the pop up.
self.pop_up.dismiss()
if __name__ == "__main__":
ExampleApp().run()

相关内容

最新更新