在 Python 中处理线程上的 GTK 对象 [英] Handling GTK Objects on Threads in Python

查看:79
本文介绍了在 Python 中处理线程上的 GTK 对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在用 Python 创建一个应用程序,该应用程序使用 GTK 来构建 UI,并且我对在线程上处理 GTK 对象(例如 GtkProgressBar 对象)没有什么困惑.

i'm creating a application in Python, that uses GTK to build the UI, and i'm little confuse about handle GTK Objects on Threads, for example, the GtkProgressBar object.

这里是上下文:

我尝试在主线程上进行下载,并且我添加了一个 GObject.timeout_add 来使进度条脉动直到下载结束.但是在第一个脉冲之后,用户界面冻结了.

I try to do a download on a Main Thread, and i add a GObject.timeout_add to pulse the bar until the Download ends. But after the first pulse the UI froze.

直到OK,线程冻结直到下载完成,所以任何组件都将被更新.解决方案:创建一个新线程.

Until there OK, the Thread froze until the download is complete, so any component will be updated. Solution: Create a new Thread.

我创建了这个新线程来制作下载和其他内容.在这个线程上,我收到了进行更新的进度条.但是当下载正在运行并且我添加 GObject.timeout_add 来使栏脉动时,UI 再次冻结.新解决方案:创建第三个线程.

I've created this new thread to make the Download, and other things. On this thread, i receive the progress bar to do the updates. But while the download is running and i add the GObject.timeout_add to pulse the bar, the UI froze again. New Solution: Create a third thread.

所以我的主题看起来像这样:

So my threads is looking lke this:

Main-Thread
    '---- Thread 1
             '------Thread 2

因此,在 Thread 1 上,我做了另一件事并更新了 UI,而在 Thread 2 中,我进行了下载并添加了 GObject.timeout_add 并在那里我可以更新进度条.在 Thread 1 我加入了 Thread 2

So, on Thread 1, i make another things and update the UI, while in Thread 2 i make the download and add the GObject.timeout_add and in there i can update the progress bar. And in Thread 1 i join the Thread 2

我使用 GObject.idle_add 函数处理 Gtk 对象.

I handle the Gtk Objects using GObject.idle_add function.

但我很困惑为什么下载和更新进度条在 Thread 2 上运行良好,而不是在 Thread 1

But i'm very confuse about why the download and the update of the progress bar works well on the Thread 2 and not on Thread 1

有人可以向我解释为什么会发生这种情况,或者我是否遗漏了有关处理 GTK 对象的内容.

Someone can explain to me why that's happen, or if i miss a something about handle GTK objects.

谢谢

推荐答案

如果阻止 Gtk 主循环,窗口和小部件将变得无响应.这就是您不能在主线程中进行下载的原因.从下载线程更新 Gtk.ProgressBar 可能会起作用,具体取决于您的实现方式.

If you block the Gtk main loop, the window and the widgets become unresponsive. That's why you cannot make the download in the main thread. Updating the Gtk.ProgressBar from the download thread could work depending on how you implemented it.

这是一种下载东西并有一个有效的 ProgressBar 的方法:

This is one way to download something and have a working ProgressBar:

from gi.repository import Gtk, GLib
import threading
import urllib.request

class Window(Gtk.Window):
    def __init__(self):
        super().__init__()
        self.connect('delete-event', Gtk.main_quit)
        self.progress = Gtk.ProgressBar()
        self.add(self.progress)
        self.show_all()

        # Start download
        self.thread = threading.Thread(target=self.download)
        self.thread.start()
        GLib.timeout_add_seconds(1, self.download_pulse)

    def download(self):
        urllib.request.urlretrieve('<link>')

    def download_pulse(self):
        if self.thread.is_alive():
            self.progress.pulse()
            return True
        return False

win = Window()
Gtk.main()

这篇关于在 Python 中处理线程上的 GTK 对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆