【问题标题】:Python 3 - Tkinter nameErrorPython 3 - Tkinter 名称错误
【发布时间】:2017-06-10 00:51:22
【问题描述】:

NameError: 名称“onOpen”未定义

命令功能有问题。我不确定我在这里做错了什么。我在 onOpen 函数之前测试了代码,它工作正常。

    import tkinter as tk
from tkinter import filedialog

class Application(tk.Frame): 
    def __init__(self, master=None):
        tk.Frame.__init__(self, master) 
        self.pack() 
        self.createWidgets()

    def onOpen():
        """ Ask the user to choose a file and update the values of label change button"""
        button_label.set(filedialog.askopenfilename(filetypes = ()))

    def createWidgets(self):

        #instruction label
        self.labelInstruct = tk.Label(self, text="Instructions:", padx=10, pady=10)
        self.labelInstruct = tk.Label(self, text="All you have to do is insert the file and save it.\n The conversion is instant", padx=10, pady=10)
        self.labelInstruct.pack()

        #insertfile button
        self.ifbut = tk.Button(self, text="Insert File", command=onOpen)
        self.ifbut.pack()

        button_label = tk.StringVar(self)
        text = tk.Label(self, textvariable = button_label)
        text.pack()

        #save button
        self.saveLabel = tk.Label(self, text="Save File", padx=10, pady=10)
        self.saveLabel.pack()
        self.saveButton = tk.Button(self)
        self.saveButton.pack()

        #quit button
        self.quitButton = tk.Button(self, text='Quit',
            command=self.quit) 
        self.quitButton.pack()

app = Application() 
app.master.title('Sample application') 
app.mainloop()

【问题讨论】:

    标签: python python-2.7 python-3.x tkinter


    【解决方案1】:

    看到这段代码的编写方式存在很多问题,我只想指出其中的一些问题并解决 OP 的主要问题。

    让我们从你需要用root = tk.Tk() 之类的东西定义主窗口开始,你还需要确保你的类中的所有方法都将参数self 作为第一个参数。

    你定义的任何变量也应该有 self 以便类可以与之交互。例如,这个 (button_label) 应该是 self.button_label

    没有理由在onOpen(self): 方法中尝试使用 return 的方式。 Return 不是那样工作的。 Return 在那里,因此您可以将值返回给正在调用函数/方法以用于其他内容而不是设置某些内容的值。

    请注意,我还将root 窗口变量添加到app = Application(root) 行。这让我们可以将主窗口传递给类。

    以下所有内容都应该适用于 onOpen(self): 函数,但其​​余部分仍需要一些工作。

    import tkinter as tk
    from tkinter import filedialog
    
    
    class Application(tk.Frame): 
        def __init__(self, parent):
            tk.Frame.__init__(self, parent) 
            self.parent = parent
            self.pack() 
            self.createWidgets()
    
        def onOpen(self):
            """ Ask the user to choose a file and update the values of label change button"""
            self.button_label.set(filedialog.askopenfilename(filetypes = ()))
    
        def createWidgets(self):
    
            #instruction label
            self.labelInstruct = tk.Label(self.parent, text="Instructions:", padx=10, pady=10)
            self.labelInstruct = tk.Label(self.parent, text="All you have to do is insert the file and save it.\n The conversion is instant", padx=10, pady=10)
            self.labelInstruct.pack()
    
            #insert file button
            self.ifbut = tk.Button(self.parent, text="Insert File", command = self.onOpen)
            self.ifbut.pack()
    
            self.button_label = tk.StringVar()
            self.text = tk.Label(self.parent, textvariable = self.button_label)
            self.text.pack()
    
            #save button
            self.saveLabel = tk.Label(self.parent, text="Save File", padx=10, pady=10)
            self.saveLabel.pack()
            self.saveButton = tk.Button(self.parent, text = "Save")
            self.saveButton.pack()
    
            #quit button
            self.quitButton = tk.Button(self.parent, text='Quit', command=self.quit) 
            self.quitButton.pack()
    
    
    root = tk.Tk()
    app = Application(root) 
    app.master.title('Sample application') 
    app.mainloop()
    

    【讨论】:

      【解决方案2】:

      你需要返回函数值如下:

      def onOpen():
          """ Ask the user to choose a file and update the values of label change button"""
          return button_label.set(filedialog.askopenfilename(filetypes = ()))    
      

      【讨论】:

      • OP 的代码有很多问题,这不是其中之一。你不要返回tkinter.label.set()
      • 猜猜,我给了一个错误的建议。正确的建议是什么?
      • 既然有这么多问题,我宁愿把这个问题标记为太宽泛。但是....只是处理 NameError,command 参数应该更改为command=self.onOpen,因为onOpen 是一个实例方法。因为它是一个实例方法,onOpen 应该接受 self 参数。 def onOpen(self):。仍然会有一些错误留给 OP 自己解决。
      • 以及您的解决方案错误的原因,因为.set() 是一种就地方法。添加一个 return 语句只是让它返回 None。就像你不这样做一样:return list.append()
      • 是的,我同意你所说的。由于onOpen是一个实例方法,所以函数应该写成def onOpen(self),命令参数应该是self.onOpen。感谢您的关注。猜猜我对一个我还不知道的话题发表了评论。
      猜你喜欢
      • 1970-01-01
      • 2018-08-23
      • 2018-08-05
      • 1970-01-01
      • 1970-01-01
      • 2012-03-20
      • 1970-01-01
      • 2014-01-18
      相关资源
      最近更新 更多