thread.join()的任何替代方法都可以更新wxPython GUI?

时间:2017-09-01 16:16:46

标签: python multithreading wxpython

我编写了一个程序,它循环播放一些给定的文件(实际上是电影文件),搜索该文件的副标题,然后下载它。这是一个wxPython GUI应用程序。现在,每次下载字幕时,我都希望用一些文本更新GUI的ListControl。代码如下:

for i in range(total_items):
    path = self.list.GetItem(i, 0) # gets the item (first column) from list control
    path = path.GetText() # contains the path of the movie file

    t = Thread(target = self.Downloader, args = (path,))
    t.start()

    t.join() # using this hangs the GUI and it can't be updated
    self.list.SetItem(i, 1, 'OK') # update the listcontrol for each download

很明显,我只想在线程完成时更新GUI。我使用了t.join(),但后来才知道它不能用于更新GUI,如本问题所述:GObject.idle_add(), thread.join() and my program hangs

现在,我想使用与该问题中所述相似的东西,但是当我使用wxPython时,我无法解决任何问题。

1 个答案:

答案 0 :(得分:1)

你想在你的线程中使用wx.CallAfter,它将使用主线程来调用你传递给它的任何东西

def Downloader(a_listbox,item_index):
    path = a_listbox.GetItem(item_index, 0) # gets the item (first column) from list control
    path = path.GetText() # contains the path of the movie file
    # do some work with the path and do your download
    wx.CallAfter(a_listbox.SetItem, i, 1, 'OK') # update the listcontrol for each download (wx.CallAfter will force the call to be made in the main thread)

...
for i in range(total_items):    
    t = Thread(target = self.Downloader, args = (self.list,i,))
    t.start()

根据您的说明(您仍然应该使用wx.CallAfter)

def Downloader(self):
    for item_index in range(total_items):
      path = self.list.GetItem(item_index, 0) # gets the item (first column) from list control
      path = path.GetText() # contains the path of the movie file
      # do some work with the path and do your download
      wx.CallAfter(self.list.SetItem, i, 1, 'OK') # update the listcontrol for 

Thread(target=self.Downloader).start()