更新wxPython GUI是否有thread.join()的替代方法?

更新wxPython GUI是否有thread.join()的替代方法?,python,multithreading,wxpython,Python,Multithreading,Wxpython,我写了一个程序,它循环浏览一些给定的文件(实际上是电影文件),搜索该文件的字幕,然后下载。这是一个wxpythongui应用程序。现在,每次下载字幕时,我都想用一些文本更新GUI的ListControl。代码如下: 范围内i的(总项目数): path=self.list.GetItem(i,0)#从列表控件获取项(第一列) path=path.GetText()#包含电影文件的路径 t=Thread(target=self.Downloader,args=(path,)) t、 开始() t、

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

范围内i的
(总项目数):
path=self.list.GetItem(i,0)#从列表控件获取项(第一列)
path=path.GetText()#包含电影文件的路径
t=Thread(target=self.Downloader,args=(path,))
t、 开始()
t、 join()#使用此选项会挂起GUI,无法更新
self.list.SetItem(i,1,'OK')#为每次下载更新listcontrol
很明显,我只想在线程完成时更新GUI。我使用了t.join(),但后来理解它不能用于更新GUI,如本问题所述:


现在,我想使用类似于那个问题中所述的东西,但我无法理解任何东西,因为我使用的是wxPython

您希望在线程内部使用
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)


很抱歉,但这对我来说不起作用。我的程序使用使用API密钥的“xmlrpc”请求,并且一次只能从单个用户帐户发出一个请求。但您提供的代码一次运行多个请求,从而生成错误。看起来,我必须找到一种方法来一个接一个地运行线程,而不是一次运行所有线程。谢谢,它成功了。事实上,我是线程新手,很抱歉没有抓住要点。@SadmanMuhibSamyo只是一个问题。如果一次只能下载一个文件,为什么要对下载进行线程化?您的代码是否同时执行其他操作。用户界面停止响应,直到所有下载完成2。我能';在所有下载完成@rolf之前,不要更新UI
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()