【问题标题】:Python crashes when trying to run tkinter with progressbar尝试使用进度条运行 tkinter 时 Python 崩溃
【发布时间】:2014-12-21 20:05:24
【问题描述】:

我正在尝试创建一个在创建文件之前运行 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,但运行程序时什么也没有发生。

【问题讨论】:

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


    【解决方案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()
    

    【讨论】:

    • 我不确定这有什么帮助。 checkfile 的 file 参数在哪里?
    • 是的,但现在它说 checkfile() 缺少 1 个必需参数 file
    • 再看一遍。我的def checkfile() 没有参数。
    • 哦!好的,现在我检查了它,运行时没有任何反应!
    • 等等,我定义了checkfile函数后,我该怎么调用?
    猜你喜欢
    • 2018-12-07
    • 1970-01-01
    • 2018-02-16
    • 2016-09-28
    • 2021-11-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多