尝试使用progressbar运行tkinter时Python崩溃

时间:2014-12-21 20:05:24

标签: windows python-3.x progress-bar ttk crash

我试图创建一个运行ttk进度条的函数,直到创建一个文件。 Widget.after似乎导致了APPCRASH,但我不知道为什么。请帮忙!

def FilePgBar(title, file):
    if root:
        root.withdraw()
        boxRoot = Toplevel(master=root)
        boxRoot.withdraw()
    else:
        boxRoot = Tk()
        boxRoot.withdraw()

    boxRoot.protocol('WM_DELETE_WINDOW', denyWindowManagerClose )
    boxRoot.title(title)
    boxRoot.iconname('Dialog')
    boxRoot.geometry(rootWindowPosition)
    boxRoot.minsize(400, 100)
    pgBar = ttk.Progressbar(boxRoot, orient=HORIZONTAL, length=300, mode='indeterminate')
    pgBar.grid(row=1, column=0)
    pgBar.pack()
    pgBar.start()
    def checkfile():
        if os.path.exists(file):
            pgBar.stop()
            pgBar.destroy()
            boxRoot.deiconify()
            boxRoot.mainloop()
            boxRoot.destroy()
            if root: root.deiconify()
        else:
            boxRoot.after(100, checkfile)

    checkfile()

我想从其他脚本调用此函数,所以我不确定使用类

编辑:我编辑了代码。我不再获得APPCRASH,但是当我运行程序时没有任何反应。

1 个答案:

答案 0 :(得分:1)

Python在将参数传递给函数之前对其进行求值。所以遇到时

boxRoot.after(100, checkfile(file))

它评估checkfile(file) - 调用checkfile - 并在调用checkfile(file)之前用函数返回的值替换boxRoot.after

由于checkfile(file)没有return语句,默认情况下会返回None。因此

boxRoot.after(100, None)

被调用。这会引发错误,因为boxRoot.after的第二个参数应该是可调用的。


相反,传递函数对象checkfile本身:

def checkfile():
    if os.path.exists(file):
        pgBar.stop()
        pgBar.destroy()     
        boxRoot.destroy()
        if root: root.deiconify()
    else:
        # You need to update the progress bar            
        boxRoot.after(100, checkfile)

这允许boxRoot.after函数从 boxRoot.after内的调用该函数,而不是在调用after之前调用该函数。


您可能会这样做:

import os
import Tkinter as tk
import ttk

class App(object):
    def __init__(self, master, *args, **kwargs):
        self.master = master
        self.button = tk.Button(master, text='Stop', command=self.stop)
        self.button.pack()
        self.progress = ttk.Progressbar(master, orient="horizontal", 
                                        length=200, mode="determinate")
        self.progress.pack()
        self.progress["value"] = 0
        self.progress["maximum"] = 100
        self.filename = '/tmp/out'
        if os.path.exists(self.filename):
            os.unlink(self.filename)
        self.checkfile()

    def checkfile(self):
        self.progress["value"] += 1
        if (not os.path.exists(self.filename) 
            and self.progress["value"] < self.progress["maximum"]):
            self.master.after(100, self.checkfile)

    def stop(self):
        with open(self.filename, 'w') as f: pass

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