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.
精彩评论