2015-10-29 4 views
0

Я создаю приложение на Python, которое использует GTK для создания пользовательского интерфейса, и я немного путаюсь с дескрипторами объектов GTK в потоках, например, с объектом GtkProgressBar.Обработка объектов GTK на потоках в Python

Вот контекст:

Я пытаюсь сделать загрузку на основной поток, и я добавить GObject.timeout_add пульсировать планку до загрузки не закончится. Но после первого импульса пользовательский интерфейс застыл.

До тех пор, пока не будет ОК, поток заморозится, пока загрузка не будет завершена, поэтому любой компонент будет обновлен. Решение. Создайте новую тему.

Я создал этот новый поток, чтобы сделать Download и другие вещи. В этом потоке я получаю индикатор выполнения, чтобы делать обновления. Но пока загрузка запущена, и я добавляю GObject.timeout_add для пульсации панели, пользовательский интерфейс снова застыл. Новое решение: создайте третий поток.

Так мои темы смотрит LKE это:

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

Так, на Thread 1, я сделать еще вещи и обновления пользовательского интерфейса, в то время как в Thread 2 я сделать загрузку и добавить GObject.timeout_add и там я могу обновить индикатор выполнения. И в Thread 1 i присоединяюсь к Thread 2

Я обрабатываю объекты Gtk с помощью функции GObject.idle_add.

Но я очень путать о том, почему загрузка и обновление индикатора выполнения хорошо работает на Thread 2, а не на Thread 1

Кто-то может мне объяснить, почему это происходит, или если я пропустить что-то о обрабатывать объекты GTK.

Спасибо

ответ

2

Если заблокировать основной цикл Gtk, окно и виджеты перестает отвечать на запросы. Вот почему вы не можете сделать загрузку в основном потоке. Обновление Gtk.ProgressBar из потока загрузки может работать в зависимости от того, как вы его реализовали.

Это один из способов, чтобы скачать что-то и есть рабочий 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() 
Смежные вопросы