【问题标题】:Status bar for csv file read读取 csv 文件的状态栏
【发布时间】:2012-07-02 15:07:42
【问题描述】:

编辑:答案如下。 self.progress.update_idletasks() 是更新进度条的秘密握手。谢谢 mgilson。

我目前正在处理一些较大的 csv 文件(有时高达 700Mb),这需要一段时间(从网络驱动器中提取)。我希望能够给用户一些反馈作为过程的状态。这导致我进入 ttk 状态栏。我查看了尽可能多的示例,然后尝试将它们应用到我的程序中,但没有成功。我认为我的问题是我正在使用 for 循环来读取我的 csv 文件,但这可能不是问题。我不知道。下面是我的代码如何工作的示例。

import csv
import Tkinter as tk
import ttk

class MAIN(tk.Frame):
    def __init__(self, master, *args, **kwargs):
        n=0
        self.filename = 'some.csv'
        tk.Frame.__init__(self, *args, **kwargs)
        frame=tk.Frame(master, **kwargs)
        frame.grid()
        getdata = tk.Button(frame, text='Get Data', command=self.csvget)
        getdata.grid(row=n)
        n+=1
        self.progress = ttk.Progressbar(frame, orient='horizontal',
                                        length =200, mode='determinate')
        self.progress.grid(row=n)
    def prog(self):
        self.progress['value']=0
        try: f=open(self.filename, 'rb')
        except: return
        read = csv.reader(f, delimiter=',')
        self.maxrows=0
        for row in read: self.maxrows+=1
        self.progress['maximum']=self.maxrows
    def csvget(self):
        try: f=open(self.filename, 'rb')
        except: return
        read = csv.reader(f, delimiter=',')
        q=0
        for row in read:
            if q%100==0: self.progress['value']=q
            elif q==self.maxrows: self.progress['value']=q
            ... do some stuff (read into lists etc.)...

root=tk.Tk()
app=MAIN(root)
app.mainloop()

结果比我预期的要长。我知道我正在阅读该文件两次。 (我无法弄清楚如何以任何其他方式获取 csv 文件的长度,如果您对此有解决方案,我会全力以赴。)但是我的问题的主要目的仍然是如何获得进度条工作。在其当前配置中,一旦文件完成读取,它就会立即从零变为满。有什么建议吗?

编辑:在 mgilson 的帮助下,我的代码变得更好了。但是我的状态栏在文件时仍然没有更新。我尝试了以下方法:

self.completed = tk.IntVar()
self.completed.set(0)
self.progress = ttk.Progressbar(self.frame, orient='horizontal', length=200,
                   mode='determinate', maximum=100, variable=self.completed)
#in the function now
fsize = os.path.getsize(self.filename)
for r,row in enumerate(read):
    q=float(f.tell())/float(fsize)*100 
    if r%100 ==0:
        self.completed.set(q)

除了调用self.completed之外,我还创建了一个def,将q作为输入,然后将其放入self.completed。另外,我没有使用self.completed,而是去掉了self.progress 中的variable kwarg,而是直接和通过def 调用kwarg 的“值”。还尝试了self.progress.configure(value = q),它的行为与其他人一样。

所有这些尝试仅在文件完成后刷新栏。

如果我在读取数据的for 循环之前修改了条形图的状态,但在相同的def 中,在文件完成读取之前,条形图不会更新。 (我尝试将其设置为 50 作为实验,文件完成后立即从无变为 100%。)

【问题讨论】:

    标签: python csv tkinter python-2.7


    【解决方案1】:

    你想要类似的东西:

    if q%100==0: 
        self.progress['value']=float(q)/100
        self.progress.update_idletasks()
    

    或许:

    self.progress.configure(value=q)
    self.progress.update_idletasks()
    

    在之前的版本中,一读到100行,进度条就会被填满。

    另外请注意,进度条只会在程序控制返回主循环后更新,除非您明确告知它(update_idletasks())。

    只要不读取文件两次,您可能可以为此使用file.tell(不保证 - 如果它不起作用,请告诉我,我会删除它建议):

    fsize=os.path.getsize(filename)
    ...
    q=f.tell()/fsize
    

    如果可行,您可以将构造函数更改为:

    self.progress = ttk.Progressbar(frame, orient='horizontal',
                                    length =200, mode='determinate',maximum=1.)
    

    和你的循环:

    for i,row in enumerate(read):
        q=f.tell()/fsize
        if i%100==0: 
            self.progress['value']=q
            self.progress.update_idletasks()
        #do stuff
    else:
        self.progress['value']=q
        self.progress.update_idletasks()
    

    另外一个说明,一般来说,有一个裸露的try/except 子句不是一个好主意。你通常想要:

    try:
       #something
    except SomeError: #IOError?  OSError? some combination of the two of them?
       #something else.
    

    只捕获您知道如何处理的异常。

    【讨论】:

    • 我正在努力应用你在那里的东西。在循环调用中,我将如何调用连续第 5 个元素?还是行[4]?我以前没见过这种格式。
    • @deadstump。是的。 enumerate 只是环绕任何迭代器并返回索引,然后返回元素。在这种情况下,元素是行(列表),因此您可以完全按照以前使用的方式使用变量 row
    • 文件大小的限制效果很好,让我免于打开文件两次。但是,进度条在获取文件时仍然不会更新自身。我做了一个小实验,并试图让酒吧在呼叫['value']=0 开始时重置它自己。它没有。在不同的 def 调用中是否有什么东西会阻止栏刷新?
    • @deadstump -- 这个类的文档很少,所以很难确定。无论如何,我添加了另一个可能有帮助的建议...
    • @deadstump -- 最后一次尝试。尝试在更新后立即添加self.progress.update_idletasks()。否则,我尝试滚动自己的状态栏,您可以免费使用。
    猜你喜欢
    • 2020-05-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-10
    • 2012-05-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多