【问题标题】:Run Kivy Application method in background在后台运行 Kivy Application 方法
【发布时间】:2015-04-23 13:08:47
【问题描述】:

我已经构建了一个桌面kivy 应用程序,其中包含一些在我的应用程序中执行更改的方法以及需要一些时间(大约 30 秒)的其他计算。当我调用这些方法时,应用程序会在它们执行期间冻结,这是不可取的。有没有办法防止应用冻结,而是显示某种带有动画 gif 的弹出窗口,以便用户知道应用正在处理某些内容并且没有崩溃/停止响应?

我尝试使用多处理在后台运行这些方法,同时出现一个信息弹出窗口,但这些进程不与主应用程序进程共享内存和数据结构。因此,即使该方法成功运行并显示了弹出窗口,应用程序中也没有任何变化......

不管怎样,这是多处理代码:

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)

任何帮助将不胜感激。

【问题讨论】:

标签: python kivy


【解决方案1】:

您的问题有一个良好的开端,但轮询 is_alive 不是您想要做的。由于您只执行一项后台任务并显示一个对话框,因此您可以为此使用线程或多处理。他们的 API 非常相似。

为避免轮询,您可以使用processing pool(更容易处理)并将回调传递给pool.apply_async

不过,此回调不会在主线程上运行,因此如果您需要在主线程上运行代码,则需要在回调中安排它。

另一种方法是只使用单独的线程而不是进程,并使用 Kivy 的时钟在线程函数结束时安排函数调用。见kivy threading docs

这个 SO 答案也是将数据从线程传输到主线程的一个选项:https://stackoverflow.com/a/22033066。来自 Kivy 开发人员。

【讨论】:

  • 因此,使用 pool.apply_async 会由于不可拾取的对象而导致一系列错误。这是因为我传递的函数是类方法而不是顶级函数?使用 Kivy 的时钟和线程,仍然会导致应用程序冻结在长循环中。我已经用this 示例修改了我的代码,但冻结仍然存在。
  • 是的,要使用多处理,从一个进程发送到另一个进程的任何内容都必须是可腌制的。如果可以腌制类对象,则可以使用类方法,但我认为 kivy 对象不能。您可以将长时间运行的函数分离到它自己的函数/对象中,或者坚持使用线程。我不太确定您在线程中看到了什么,因为没有示例代码可供尝试。
  • 使用线程,如果我将@mainthread 装饰器放在目标函数上,它会冻结应用程序,一切都是normal。当我删除 @mainthread 装饰器时,应用程序不会冻结但我得到 this
  • @mainthread 将在主(GUI)线程上运行整个函数。需要很长时间的函数应该在后台线程中运行。然后在该函数结束时,当它完成工作时,您调用第二个函数。第二个函数可以使用 @mainthread 装饰器或使用 Clock 进行调度。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-02-03
  • 2019-07-22
  • 2013-06-20
  • 1970-01-01
  • 2021-02-10
  • 1970-01-01
相关资源
最近更新 更多