0

我目前正在为 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()
4

2 回答 2

0

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

于 2013-09-25T04:35:54.150 回答
0

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

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

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

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

另一个可能更容易的选择是使用 python 的多处理模块将 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
于 2013-09-19T16:19:45.357 回答