Menangani Objek GTK pada Thread dengan Python

Saya membuat aplikasi dengan Python, yang menggunakan GTK untuk membangun UI, dan saya sedikit bingung menangani Objek GTK di Threads, misalnya objek GtkProgressBar.

Inilah konteksnya:

Saya mencoba melakukan pengunduhan di Thread Utama, dan saya menambahkan GObject.timeout_add untuk menggerakkan bilah hingga Pengunduhan berakhir. Namun setelah pulsa pertama UI membeku.

Sampai disana OK, Thread dibekukan hingga download selesai, jadi komponen apa pun akan diperbarui. Solusi: Buat Thread baru.

Saya membuat thread baru ini untuk melakukan Download, dan hal lainnya. Di thread ini, saya menerima bilah kemajuan untuk melakukan pembaruan. Namun saat pengunduhan sedang berjalan dan saya menambahkan GObject.timeout_add ke bilah pulse, UI terhenti lagi. Solusi Baru: Buat thread ketiga.

Jadi thread saya terlihat seperti ini:

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

Jadi, di Thread 1, saya membuat hal lain dan memperbarui UI, sementara di Thread 2 saya mengunduh dan menambahkan GObject.timeout_add dan di sana saya dapat memperbarui bilah kemajuan. Dan di Thread 1 saya bergabung dengan Thread 2

Saya menangani Objek Gtk menggunakan fungsi GObject.idle_add.

Tapi saya sangat bingung mengapa pengunduhan dan pembaruan bilah kemajuan berfungsi dengan baik di Thread 2 dan tidak di Thread 1

Seseorang dapat menjelaskan kepada saya mengapa hal itu terjadi, atau jika saya melewatkan sesuatu tentang menangani objek GTK.

Terima kasih


person Vitor Villar    schedule 29.10.2015    source sumber


Jawaban (1)


Jika Anda memblokir loop utama Gtk, jendela dan widget menjadi tidak responsif. Itu sebabnya Anda tidak dapat mengunduh di thread utama. Memperbarui Gtk.ProgressBar dari thread unduhan dapat berhasil bergantung pada cara Anda menerapkannya.

Ini adalah salah satu cara untuk mengunduh sesuatu dan memiliki ProgressBar yang berfungsi:

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()
person elya5    schedule 30.10.2015