在整个过程完成之前,Python GUI不会更新

时间:2011-02-08 23:23:20

标签: python user-interface listview wxpython

我有一个进程从目录中获取文件并将它们放入列表中。然后它在循环中迭代该列表。循环的最后一行是它应该更新我的gui显示,然后它再次开始循环,列表中的下一个项目。

我的问题是它实际上并没有更新gui,直到整个过程完成,这取决于列表的大小可能是30秒到超过一分钟。这给了程序“挂”的感觉

我想要它做的是处理列表中的一行,更新gui然后继续。我哪里做错了?更新列表的行是#populate listview with drive contents。 print语句仅用于调试。

def populateList(self):
    print "populateList"

    sSource = self.txSource.Value
    sDest = self.txDest.Value

    # re-intialize listview and validated list
    self.listView1.DeleteAllItems()
    self.validatedMove = None
    self.validatedMove = []

    #Create list of files
    listOfFiles = getList(sSource)    

    #prompt if no files detected
    if listOfFiles == []:
        self.lvActions.Append([datetime.datetime.now(),"Parse Source for .MP3 files","No .MP3 files in source directory"])

    #Populate list after both Source and Dest are chosen
    if len(sDest) > 1 and len(sDest) > 1:     
        print "-iterate listOfFiles"

        for file in listOfFiles:
            sFilename = os.path.basename(file)
            sTitle = getTitle(file)
            sArtist = getArtist(file)
            sAlbum = getAblum(file)

            # Make path = sDest + Artist + Album
            sDestDir = os.path.join (sDest, sArtist)
            sDestDir = os.path.join (sDestDir, sAlbum) 

            #If file exists change destination to *.copyX.mp3
            sDestDir = self.defineDestFilename(os.path.join(sDestDir,sFilename))

            # Populate listview with drive contents       
            self.listView1.Append([sFilename,sTitle,sArtist,sAlbum,sDestDir])

            #populate list to later use in move command
            self.validatedMove.append([file,sDestDir])
            print "-item added to SourceDest list"
    else:
        print "-list not iterated"

3 个答案:

答案 0 :(得分:4)

创建一个工作线程/进程,在后台进行处理并在处理完成后更新GUI,也可以在工作期间报告进度。

查看threadingmultiprocessing模块。

答案 1 :(得分:3)

这是GUI程序的常见问题。在收到并处理“重绘”命令之前,控件不会更新,并且在函数返回之前不会发生。

您可以通过调用Update方法强制控件重新绘制,如此问题的答案所示:How do you force refresh of a wx.Panel?

答案 2 :(得分:0)

我可能会建议您尝试wx.lib.delayedresult。它是某种简化的多线程解决方法。您可以将业务逻辑放入工作者功能和消费者功能中的其他逻辑(包括GUI附加,更新)。 worker函数在另一个线程中运行,而使用者函数保证在主线程中完成worker函数后运行。