【问题标题】:Python GUI does not update until entire process is finished在整个过程完成之前,Python GUI 不会更新
【发布时间】:2011-06-23 19:19:10
【问题描述】:

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

我的问题是,直到整个过程完成,它才会真正更新 gui,这取决于列表的大小可能是 30 秒到一分钟多。这给人一种程序“挂起”的感觉

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

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"

【问题讨论】:

    标签: python user-interface listview wxpython


    【解决方案1】:

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

    查看threadingmultiprocessing 模块。

    【讨论】:

      【解决方案2】:

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

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

      【讨论】:

      • 我对 python 很陌生,所以我无法让更新方法工作。我尝试在 append 命令之后插入几个 self.Update() 变体。其中一些造成了错误,而另一些则没有明显的影响。你能给我一个额外的推动吗?
      • 我不知道为什么,但是在继续玩一些之后 self.Update() 开始工作。但现在它更新了,在处理它时我无法使用滑块。有什么想法吗?
      【解决方案3】:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-06-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多