python 基维 : Properly start a background process that updates GUI elements

标签 python event-handling kivy

我有一个 Python 脚本,可以对用户文件执行一些密集处理,这可能需要一些时间。我使用 Kivy 为它构建了一个用户界面,允许用户选择文件、处理模式并在过程进行时向他们显示一些消息。

我的问题是,当主 Kivy 循环调用底层用户界面时,窗口卡住。

据我所知,解决此问题的正确方法是创建一个单独的进程,脚本将卸载到该进程,并将更新从该进程发送到用户界面。

但是,我找不到如何执行此操作的示例或有关如何将消息从单独的线程发送回应用程序的任何规范。

有人可以举例说明如何正确地执行此操作或向我指出与该主题相关的文档吗?

更新:

为了保持程序的可维护性,我想避免从主线程调用处理器循环的元素,而是调用一个长进程返回到更新的 GUI 元素,例如进度条或文本域。看起来这些元素只能从主 kivy 线程修改。我如何从外部访问它们?

最佳答案

按照描述使用发布者/消费者模型 here .这是该链接中的一个示例,已修改为使用单独的线程:

from kivy.app import App
from kivy.clock import Clock, _default_time as time  # ok, no better way to use the same clock as kivy, hmm
from kivy.lang import Builder
from kivy.factory import Factory
from kivy.uix.button import Button
from kivy.properties import ListProperty

from threading import Thread
from time import sleep

MAX_TIME = 1/60.

kv = '''
BoxLayout:
    ScrollView:
        GridLayout:
            cols: 1
            id: target
            size_hint: 1, None
            height: self.minimum_height

    MyButton:
        text: 'run'

<MyLabel@Label>:
    size_hint_y: None
    height: self.texture_size[1]
'''

class MyButton(Button):
    def on_press(self, *args):
        Thread(target=self.worker).start()

    def worker(self):
        sleep(5) # blocking operation
        App.get_running_app().consommables.append("done")

class PubConApp(App):
    consommables = ListProperty([])

    def build(self):
        Clock.schedule_interval(self.consume, 0)
        return Builder.load_string(kv)

    def consume(self, *args):
        while self.consommables and time() < (Clock.get_time() + MAX_TIME):
            item = self.consommables.pop(0)  # i want the first one
            label = Factory.MyLabel(text=item)
            self.root.ids.target.add_widget(label)

if __name__ == '__main__':
    PubConApp().run()

关于 python 基维 : Properly start a background process that updates GUI elements,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26302572/

相关文章:

python - 如何允许 Tkinter 从列表输入生成列表框

C# .NET 正确的事件订阅和取消订阅

javascript - 如何制作 HTML5 Canvas "Press/Click to play"开始屏幕

android - 绑定(bind)多个语句以在 kivy 中尝试表达式

python 多处理示例 itertools 多个列表

python - 使用 Beautifulsoup Python 从 URL 抓取数据时获取编码文本

python - Kivy 桌面中的热键

python - 属性错误 : 'MainRouter' object has no attribute '_disabled_count'

python - 正则表达式检测双花括号之间的文本

javascript - 有没有办法用 Javascript 跟踪选项卡上的焦点?