Python GUI не обновляется, пока не завершится весь процесс - PullRequest
2 голосов
/ 09 февраля 2011

У меня есть процесс, который получает файлы из каталога и помещает их в список. Затем он повторяет этот список в цикле. Последняя строка цикла, где он должен обновить мой графический интерфейс, затем снова начинает цикл со следующего элемента в списке.

Моя проблема в том, что он фактически не обновляет графический интерфейс, пока не завершится весь процесс, который в зависимости от размера списка может составлять от 30 секунд до более минуты. Это создает ощущение зависания программы

Я хотел, чтобы он обработал одну строку в списке, обновил графический интерфейс и затем продолжил. Где я неправ? Строка для обновления списка: # Заполнить просмотр списка содержимым диска. Операторы печати предназначены только для отладки.

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 ]

4 голосов
/ 09 февраля 2011

Создайте рабочий поток / процесс, который выполняет вашу обработку в фоновом режиме и обновляет графический интерфейс после завершения обработки, возможно, сообщая о ходе работы.

Посмотрите на threading или многопроцессорные модули.

3 голосов
/ 09 февраля 2011

Это общая проблема с программами с графическим интерфейсом.Элементы управления не обновляются до тех пор, пока не будет получена и обработана команда «repaint», а этого не произойдет, пока ваша функция не вернется.

Вы можете принудительно перерисовать элемент управления в любое время, вызвав его Update метод, как показано в ответе на этот вопрос: Как принудительно обновить wx.Panel?

0 голосов
/ 26 февраля 2011

Я мог бы предложить вам попробовать wx.lib.delayedresult . Это как-то упрощенный многопоточный обходной путь. Вы можете поместить свою бизнес-логику в рабочую функцию и другую логику (включая добавление, обновление графического интерфейса) в потребительскую функцию. Рабочая функция выполняется в другом потоке, в то время как потребительская функция гарантированно выполняется после завершения рабочей функции в основном потоке.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...