有没有办法只在gobject.idle_add()函数终止时继续?

时间:2012-01-08 15:08:31

标签: python multithreading iterator gtk pygtk

我想下载图片并使用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 个答案:

答案 0 :(得分:1)

我找到了一个解决方案:在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