简体   繁体   中英

Python GUI tkinter NameError

Im new here, and i have a problem on a quiz im working with Python Tkinter.

So here is the code:

b5 = Button(root, text="Next Question",command=question_2_output)
b5.configure(command = des)
b5.pack(side=BOTTOM)

With this button im trying to acess on two functions. -->

def question_2_output():

    lab7 = Label(root, text="Qestion 2 Qestion 2 Qestion 2 Qestion 2", 
    font="Verdana 11 italic")
    lab7.pack()
    lab7.place(x = 350, y = 60)


def des():
    q1.destroy()

With this code i try to put lab7 on the same place the previous Question q1 were and destroy/delete the older Label (Question). But i get this error NameError: name 'q1' is not defined. I cant destroy q1. q1 is in this function.

def question_1_output():
    q1 = Label(root, text="This is a very very very very very long question?", font="Verdana 11 italic")
    q1.pack()
    q1.place(x = 350, y = 60)

Any help?? Thanks!

I think you might be better off just updated the label instead of destroying it and adding a new one.

I would also use a class to build this GUI as it will be easier to use class attributes and cleaner to read. Avoiding the use of global is a good practice and we can do this with class attributes.

Here is a simple example of how you can go about updating the label and button.

import tkinter as tk


class GUI(tk.Frame):
    def __init__(self, parent, *args, **kwargs):
        tk.Frame.__init__(self, parent, *args, **kwargs)
        self.parent=parent
        self.question_label = tk.Label(self, text="Question 1", font="Verdana 11 italic")
        self.question_label.pack()
        self.b1 = tk.Button(self, text="Next Question",command=self.question_2_output)
        self.b1.pack(side=tk.BOTTOM)

    def question_1_output(self):
        self.question_label.config(text="Question 1")
        self.b1.configure(text="Next Question", command=self.question_2_output)

    def question_2_output(self):
        self.question_label.config(text="Question 2")
        self.b1.configure(text="Previous Question", command=self.question_1_output)


if __name__ == "__main__":
    root = tk.Tk() 
    GUI(root).pack()
    tk.mainloop()

Declare it as a global variable q1 in your question_1_output() function and des() function

def des():
    global q1
    q1.destroy()


def question_1_output():
    global q1
    q1 = Label(root, text="This is a very very very very very long question?", font="Verdana 11 italic")
    q1.pack()

And to let you button execute two function you can do it this way

b5 = Button(root, text="Next Question", command=lambda:[des(), question_2_output()])
b5.pack(side=BOTTOM)

q1 is in the local scope of the function question_1_output and thus not visible in the function des .

Reorder the definitions or return the object from the function, like this:

def question_1_output():
    q1 = Label(root, text="This is a very very very very very long question?", font="Verdana 11 italic")
    q1.pack()
    q1.place(x = 350, y = 60)
    return q1

def des(question):
    question.destroy()

q1 = question_1_output()
des(q1)

Though I don't see the point of the function des if it merely calls destroy on the object.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM