简体   繁体   中英

Handling GTK Objects on Threads in Python

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.

Here is the context:

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.

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

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

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

I handle the Gtk Objects using GObject.idle_add function.

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

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

Thank you

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.

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()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM