Python csv文件读取的状态栏
编辑:答案如下Python csv文件读取的状态栏,python,csv,tkinter,python-2.7,Python,Csv,Tkinter,Python 2.7,编辑:答案如下self.progress.update_idletasks()是更新进度条的秘密握手。谢谢你,麦吉尔森 我目前正在处理一些较大的csv文件(有时高达700Mb),这需要一段时间(从网络驱动器中提取)。我希望能够给用户一些反馈作为进程的状态。这将我引导到ttk状态栏。我看了尽可能多的例子,然后试图将它们应用到我的程序中,但没有成功。我想我的问题是我正在使用for循环来读取我的csv文件,但这可能不是问题所在。我不知道。下面是我的代码如何工作的示例 import csv import
self.progress.update_idletasks()
是更新进度条的秘密握手。谢谢你,麦吉尔森
我目前正在处理一些较大的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
中去掉了变量kwarg,并返回到直接调用和通过def
调用kwarg'value'。还尝试了self.progress.configure(value=q)
,其行为与其他操作相同
所有这些尝试仅在文件完成后刷新栏
如果我在读取数据的for
循环之前修改了条形图的状态,但在相同的def
中,直到文件读取完毕,条形图才会更新。(作为一个实验,我试着将其设置为50,文件一完成,它就从零变为100%)您想要类似于:
if q%100==0:
self.progress['value']=float(q)/100
self.progress.update_idletasks()
或许:
self.progress.configure(value=q)
self.progress.update_idletasks()
对于上一个版本,只要你读了100行,进度条就会被填满
另外请注意,除非您明确地告诉进度条,否则只有在程序控制返回到mainloop时才会更新进度条(使用update\u idletasks()
)
至于不读取文件两次,您可以使用文件。告诉(不保证——如果不起作用,请告诉我,我将删除此建议):
如果这样做有效,您可以将构造函数更改为:
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.
仅捕获您知道如何处理的异常。是否需要类似以下内容:
if q%100==0:
self.progress['value']=float(q)/100
self.progress.update_idletasks()
或许:
self.progress.configure(value=q)
self.progress.update_idletasks()
对于上一个版本,只要你读了100行,进度条就会被填满
另外请注意,除非您明确地告诉进度条,否则只有在程序控制返回到mainloop时才会更新进度条(使用update\u idletasks()
)
至于不读取文件两次,您可以使用文件。告诉(不保证——如果不起作用,请告诉我,我将删除此建议):
如果这样做有效,您可以将构造函数更改为:
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。对<代码>枚举
只需环绕任何迭代器并返回索引,然后返回元素。在本例中,元素是行(列表),因此您可以使用变量row
,就像您以前使用它一样。文件大小的边界非常有效,可以避免我打开文件两次。但是,进度条在获取文件时仍然不会更新其自身。我做了一个小实验,试图在调用开始时让条形图重置它自己['value']=0
。没有。在不同的def调用中,是否存在阻止刷新条的因素?@deadstump——此类上的文档非常稀少,因此很难确定。不管怎样,我添加了另一个建议,可能会有帮助…@deadstump——最后一次尝试。尝试在更新后立即添加self.progress.update\u idletasks()
。否则,我试着滚动我自己的状态栏,你可以自由使用。我正在努力应用你的状态栏。在循环调用中,我如何调用一行中的第5个元素?还是排[4]?我以前从未见过这种格式。@deadstump。对<代码>枚举
只需环绕任何迭代器并返回索引,然后返回元素。在本例中,元素是行(列表),因此您可以使用变量row
,就像您以前使用它一样。文件大小的边界非常有效,可以避免我打开文件两次。但是,进度条在获取文件时仍然不会更新其自身。我做了一个小实验,试图在调用开始时让条形图重置它自己['value']=0
。没有。在不同的def调用中,是否存在阻止刷新条的因素?@deadstump——此类上的文档非常稀少,因此很难确定。不管怎样,我添加了另一个建议,可能会有帮助…@deadstump——最后一次尝试。尝试添加sel