开发者

Python GUI does not update until entire process is finished

I have a process that gets a files from a directory and puts them in a list. It then iterates that list in a loop. The last line of the loop being where it should update my gui display, then it begins the loop again with the next item in the list.

My problem is that it does not actually update the gui until the entire process is complete, which depending on the size of the list could be 30 seconds to over a minute. This gives the feeling of the program being 'hung'

What I wanted it to do was to process one line in the list, update the gui and then continue. Where did I go wrong? The line to update the list is # Populate listview with drive contents. The print statements are just for debug.

def populateList(self):
    print "populateList"

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

    # re-intialize listview and validated list
    self.lis开发者_开发知识库tView1.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"


Create a worker thread/process that does your processing in the background and updates the GUI after the processing is done, maybe reporting progress during work.

Have a look at the threading or multiprocessing modules.


This is a common problem with GUI programs. Controls don't get updated until a "repaint" command is received and processed, and that won't happen until your function returns.

You can force a control to repaint at any time by calling its Update method, as shown in the answer to this question: How do you force refresh of a wx.Panel?


I might suggest you try wx.lib.delayedresult. It is somehow the simplified multithread workaround. You can put your business logic into worker function and other logics (including GUI appending, updating) in consumer function. The worker function runs in another thread while the consumer function is guaranteed to run after the finish of worker function in main thread.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜