如何使这两个函数在python中工作?

时间:2015-04-22 01:05:41

标签: python tkinter

我正在学习Python。为什么我会收到错误Exception in Tkinter callback? 我正在尝试从“浏览”按钮浏览文件并在“压缩”按钮中压缩文件。我不知道我的代码有什么问题?请帮忙!

    from Tkinter import *
    import tkFileDialog
    import gzip

    class SecureBox(Frame):

        def browse(self):
            return tkFileDialog.askopenfilename()

        def compressFile(self):   
            f_in = open(self.browse, 'rb')
            f_out = gzip.open('compressFile.gz', 'wb')
            f_out.writelines(f_in)
            f_out.close()
            f_in.close()

        def createWidgets(self):
            # Pick a file from user
            self.compress = Button(self)
            self.compress["text"] = "1. Browse"
            self.compress["command"] = self.browse
            self.compress["fg"] = "blue"
            self.compress.pack({"side": "top"})            

            # Pick a file from user and compress the file
            self.compress = Button(self)
            self.compress["text"] = "2. Compress"
            self.compress["command"] = self.compressFile
            self.compress["fg"] = "blue"
            self.compress.pack({"side": "top"})
# Adding this function to get the widget show up
        def __init__(self, master):
            Frame.__init__(self, master)
            self.pack()
            self.createWidgets() 
    root = Tk()
    root.title ("Secure Box")
    root.geometry("500x350")

    sb = SecureBox(root)
    # start the program
    sb.mainloop()

    root.destroy()

1 个答案:

答案 0 :(得分:2)

将文件名保存为类属性,并使用该属性打开文件:

def browse(self):
    self.filename = tkFileDialog.askopenfilename()

def compressFile(self):   
    f_in = open(self.filename, 'rb')
    ...

<强>解释

基本上,当您执行open(self.browse, 'rb')时,您将函数引用传递给open而不是文件名。这不会起作用,因为open无法打开函数,它可以打开文件。您可以使用open(self.browse(), 'rb'),因为self.browse()会返回文件名,但这会导致您的Browse按钮失效,因为当您单击Compress按钮时会打开文件对话框。

将文件名保存为类属性并使用它来打开上面提到的文件时,您也不需要return函数中的browse。在Tkinter中,在没有任何参数的情况下调用按钮回调,并且不保存任何返回参数,因此返回任何内容都不会执行任何操作。如果您选择完全删除浏览按钮并使用open(self.browse(), 'rb')方法,则需要返回文件名(但它不需要是类属性)。