【问题标题】:Tkinter indeterminate progress bar not runningTkinter不确定进度条未运行
【发布时间】:2013-09-24 19:39:12
【问题描述】:

我目前正在为 Python 2.7 创建 Tkinter Gui,但无法使用进度条。我需要将较大的文件加载到我的程序中,这需要一些时间,所以我想获得一个进度条来向用户显示程序没有冻结加载文件。不幸的是,我的进度条在加载文件时似乎没有更新:(我尝试为进度条创建一个新线程但没有运气。所以我想知道我需要做什么才能让不确定的进度条在一个繁重的函数调用?

我的代码的相关部分如下所示:

import Tkinter as tk
import ttk as ttk
import pandas as pd
import tkFileDialog as tfgiag

self.pb = ttk.Progressbar(frame, orient=tk.VERTICAL, mode='indeterminate')
mynewdata = tfgiag.askopenfilenames(parent=root,title='Choose a file',filetypes=[('CSV files', '.csv')])
self.t = threading.Thread(target = self.pb.start)
self.t.start()  
#read in each CSV file selected by the user
for myfile in root.tk.splitlist(mynewdata): 
    foo = pd.read_csv(myfile)    
    self.data.appendMainData(foo)
self.pb.stop()

【问题讨论】:

    标签: python pandas tkinter progress-bar


    【解决方案1】:

    Python“线程”仍然通过所谓的 GIL(全局解释器锁)按顺序锁定在一起。这基本上意味着从同一个 python 进程产生的线程不会像你希望的那样并行运行。相反,他们都在主要的 python 进程上争取时间。

    在您的情况下,如果您尝试使用一次进程监控一个密集的进程,它可能会占用 GIL,而不是将其释放到线程。

    一个选项:尝试使用 readline 方法,这样它将文件输入工作拆分到足以插入进度条更新行的程度。

    openfile = open(filename, 'r')
    for eachline in openfile.readlines():
        append_line(eachline)
        update_progressBar()
    

    另一个可能更简单的选项是使用 python 的multiprocessing 模块将 csv 文件打开到另一个进程。这模拟了您可能更习惯的线程。我将启动一个读取 csv 的新进程,并将这些行附加到队列中。完成后,向队列附加一个标记值,表示它已完成,因此主进程知道何时停止更新进度条并加入生成的进程。比如:

    import Tkinter as tk
    import ttk as ttk
    import pandas as pd
    import tkFileDialog as tfgiag
    from multiprocessing import Process, Queue
    
    self.pb = ttk.Progressbar(frame, orient=tk.VERTICAL, mode='indeterminate')
    mynewdata = tfgiag.askopenfilenames(parent=root,title='Choose a file',filetypes=[('CSV files', '.csv')])
    
    csvqueue=Queue(1) #A mp-enabled queue with one slot to results.
    #read in each CSV file selected by the user
    offloadedProcess=Process(target=csvread, args=(filename, outputqueue))
    offloadedProcess.start()
    procNotDone=False
    while procNotDone:
        result = getNewResultFromQueue(outputqueue) #pesudo code
        update_ProgressBar() #<--- this should get hit more often now
        if result.isLastValue:
            offloadedProcess.join() #Join the process, since its now done
        else:
            csvresults.append(result)
    
    
    def csvreadOffload(filename, outputqueue):
        for myfile in root.tk.splitlist(mynewdata): 
            foo = pd.read_csv(myfile)    
            if foo is not END:#Pesudo code here
                outputqueue.append(foo)
            else:
                outputqueue.append('Empty results')#pseudo code
    

    【讨论】:

      【解决方案2】:

      在每个self.pb.step(x) 语句之后使用self.frame.update_idletasks(),其中“x”代表进度条值增加的值

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-11-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-07-11
        • 1970-01-01
        相关资源
        最近更新 更多