Есть ли способ продолжить только после завершения функции gobject.idle_add ()? - PullRequest
0 голосов
/ 08 января 2012

Я хочу загрузить изображения и показать прогресс с gtk.ProgressBar().

Для этого я использовал метод, рекомендованный в PyGTK FAQ , и он отлично работает:

class MainInterface :
  def __init__(self) :
    ...
    thread.start_new_thread(self.getMap, ())

    gtk.gdk.threads_init()
    gtk.gdk.threads_enter()
    gtk.main()
    gtk.gdk.threads_leave()

  def getMap(self) :
    ...
    getImage = self.getImages(new_img_list) # new_img_list is a list of image paths
    gobject.idle_add(getImage.next)

  def getImages(self, img_list) :
    nb_img = len(img_list)
    i = 1.0
    for img in img_list :
        self.progress_interface.progress_bar.set_fraction(i/nb_img)
        gtk.gdk.threads_enter()
        get_maps.download_image(img)    # This function downloads the current image to the disk
        gtk.gdk.threads_leave()
        i += 1.0
        yield True
    self.progress_interface.progress_bar.set_text("Les images sont à jour")
    self.progress_interface.progress_bar.set_fraction(1)
    yield False

Теперь у меня есть метод ShowMap(), который создает gtk.Pixbuf из ранее загруженных изображений.

Итак, я хочу вызвать эту функцию ShowMap(), когда загружены все изображения в new_img_list (например, когда getImage.next() возвращает Falsè).

Как я могу это сделать?

Спасибо

1 Ответ

1 голос
/ 08 января 2012

Я нашел решение: начать ShowMap() в новом потоке в getImages(), например:

def getImages(self, img_list) :
    nb_img = len(img_list)
    i = 1.0
    for img in img_list :
        self.progress_interface.set_progress(i, nb_img)
        gtk.gdk.threads_enter()
        get_maps.download_image(img)
        gtk.gdk.threads_leave()
        i += 1.0
        yield True
    self.progress_interface.progress_bar.set_text("Les images sont à jour")
    self.progress_interface.progress_bar.set_fraction(1)
    thread.start_new_thread(self.ShowMap, ()) # Here
    yield False

Но, может быть, у него есть лучшее решение?

РЕДАКТИРОВАТЬНа самом деле это решение не работает в Windows (но работает в Linux), поэтому, вероятно, это неправильный способ сделать это.

РЕДАКТИРОВАТЬ 2: Я наконец-то нашел решение, используя также функцию генераторачтобы постепенно добавлять строки в gtk.IconView и передавать его в gobject.idle_add():

def getImages(self, img_list) :
    nb_img = len(img_list)
    i = 1.0
    for img in img_list :
        self.progress_interface.set_progress(i, nb_img)
        gtk.gdk.threads_enter()
        get_maps.download_image(img)
        gtk.gdk.threads_leave()
        i += 1.0
        yield True
    self.progress_interface.progress_bar.set_text("Les images sont à jour")
    self.progress_interface.progress_bar.set_fraction(1)
    map_loading = self.loadMap()
    gobject.idle_add(map_loading.next)
    yield False

def loadMap(self, step=128) :
    i = 1.0
    nb_tiles = len(self.graph) * len(self.graph[0])
    self.grid.iconview.freeze_child_notify()
    for row in self.graph :
        for col in row :
            ...
            self.grid.listStore.append(...)
            self.progress_interface.progressbar_map.set_fraction(i/nb_tiles)
            self.progress_interface.progressbar_map.set_text("Chargement des tuiles en cours ...")
            i += 1.0
            if (i % step) == 0:
                self.grid.iconview.thaw_child_notify()
                yield True
                self.grid.iconview.freeze_child_notify()
    self.grid.iconview.set_model(self.grid.listStore)
    self.grid.iconview.thaw_child_notify()
    yield False
...