我已经构建了一个桌面kivy应用程序,其中包含一些在我的应用程序中执行更改的方法以及需要一些时间(大约30秒)的其他计算。当我调用这些方法时,应用程序在执行期间会冻结,这是不可取的。有没有办法阻止应用程序冻结,而是显示某种带有动画gif的弹出窗口,以便用户知道应用程序正在处理某些内容并且没有崩溃/停止响应?
我尝试使用多处理在后台运行这些方法,同时显示信息性的Popup,但这些进程不与主应用程序进程共享内存和数据结构。因此,即使方法成功运行并显示弹出窗口,应用程序也没有变化......
无论如何,这是多处理代码:
def run_in_background(self, func, *args):
def run_func(m, a):
# Execute the function with args
m(*a)
def check_process(proc, dt):
if not proc.is_alive():
Clock.unschedule(check_func)
self.dismiss_popup()
# Create background process and start it
p = multiprocessing.Process(target=run_func, args=(func, args))
p.start()
# Create waiting dialog
content = CrunchData()
# Show waiting popup
self.show_popup(title="Some title", content=content, size=(400, 300))
# Create schedulled check for process state
check_func = partial(check_process, p)
Clock.schedule_interval(check_func, .1)
非常感谢任何帮助。
答案 0 :(得分:1)
你的问题已经有了一个良好的开端,但轮询is_alive不是你想要做的。由于您只执行一个后台任务并显示一个对话框,因此可以使用线程或多处理。他们的API非常相似。
为了避免轮询,您可以使用processing pool(更容易处理)并将回调传递给pool.apply_async
。
这个回调不会在主线程上运行,所以如果你需要在主线程上运行代码,你需要在回调中安排它。
另一种方法是使用单独的线程而不是进程,并使用Kivy的时钟在线程函数结束时调度函数调用。请参阅kivy threading docs。
此SO答案也是将数据从线程传输到主线程的选项:https://stackoverflow.com/a/22033066。它来自Kivy开发。