Python 对于UI框架中的长时间运行的数据生成器,是否应该在事件循环中执行此操作?

Python 对于UI框架中的长时间运行的数据生成器,是否应该在事件循环中执行此操作?,python,multithreading,user-interface,clutter,Python,Multithreading,User Interface,Clutter,考虑一下混乱和启蒙。它们都提供了idler,并将事件回调添加到事件循环中。两人似乎都不提倡使用线程,而是建议使用事件驱动编程 但是,如果您有一个数据生成器,它在返回之前占用了数秒的处理时间,该怎么办 在空闲器或事件循环中添加这种处理肯定会停止UI的响应吗 您应该如何使用UI框架来做这些事情 仅供参考-我们正在Python中使用这两种框架 谢谢。如果您的生产者代码不能分解成小块,那么您肯定应该使用线程。给定GL的线程模型(状态机的上下文存储在线程本地存储中),杂波与GTK+一样,甚至比GTK+更不

考虑一下混乱和启蒙。它们都提供了idler,并将事件回调添加到事件循环中。两人似乎都不提倡使用线程,而是建议使用事件驱动编程

但是,如果您有一个数据生成器,它在返回之前占用了数秒的处理时间,该怎么办

在空闲器或事件循环中添加这种处理肯定会停止UI的响应吗

您应该如何使用UI框架来做这些事情

仅供参考-我们正在Python中使用这两种框架


谢谢。

如果您的生产者代码不能分解成小块,那么您肯定应该使用线程。给定GL的线程模型(状态机的上下文存储在线程本地存储中),杂波与GTK+一样,甚至比GTK+更不能被不同的线程使用,除了调用杂波init()和杂波main()的线程之外;另一方面,使用GMainLoop工具将UI更新从线程调度到主循环是完全可以接受的

Clutter提供了一个如何在Git存储库中实现此模式的示例:


简言之,在线程内执行阻塞操作时,您应该使用gobject.idle_add()来计划UI更新。

实际上,在没有线程的情况下,使用
gobject.idle_add
和生成器函数可以更好地实现这一点:

def my_task(data):
    # ...some work...
    while heavy_work_needed:
        ...do heavy work here...
        progress_label.set_text(data) # here we update parts of UI
        # there's more work, return True
        yield True
    # no more work, return False
    yield False

def on_start_my_task_button_click(data):
    task = my_task(data)
    gobject.idle_add(task.next)

如果我阅读正确,请参阅此了解详细信息。

杂波与
gobject
组合。在这种情况下,您可以在后台线程中使用
gobject.idle\u add(func)
“gobject.idle\u add()函数添加一个函数(通过回调指定),以便在默认主循环没有挂起更高优先级事件时调用”-因此,我认为主循环上下文将由回调持有-即,不会产生单独的线程…?我的意思是,您可以尝试GTK中的默认方式如何与线程交互,请参阅此内容,谢谢-是的,这看起来是一个潜在的赢家。从FAQ中的描述来看,我的怀疑似乎是正确的。谢谢-这就是我的怀疑。我是否正确地假设“不能由不同的线程使用,除非调用了杂波_init()和杂波_main()”的线程可以是任何线程,并且不一定需要是调用main()的同一线程?否,杂波在杂波_init()内初始化GL上下文,以允许在主循环开始之前创建GL资源。因此,如果您想创建一个线程来处理混乱中的UI,您需要使用该线程来调用混乱初始化()和混乱主()。我需要多读一些书才能正确理解它。