I just finished a program, it worked perfectly, then I changed a bit of it, and now it won't work at all, even if I change it back.

self.secret_txt = Text(self, width = 35, height = 5, wrap = WORD).grid(row = 3, column = 0, columnspan = 2, sticky = W)

That it the code which is faulty.
I tried to change wrap = WORD to wrap = CHAR (just to see the change), and got this error: AttributeError: 'NoneType' object has no attribute 'delete'
'delete' comes from here:

self.secret_txt.delete(0.0, END)

Now I always get the error, even when using wrap = WORD, and also in new programs.

Help please!

I just finished a program, it worked perfectly, then I changed a bit of it, and now it won't work at all, even if I change it back.

self.secret_txt = Text(self, width = 35, height = 5, wrap = WORD).grid(row = 3, column = 0, columnspan = 2, sticky = W)

That it the code which is faulty.
I tried to change wrap = WORD to wrap = CHAR (just to see the change), and got this error: AttributeError: 'NoneType' object has no attribute 'delete'
'delete' comes from here:

self.secret_txt.delete(0.0, END)

Now I always get the error, even when using wrap = WORD, and also in new programs.

Help please!

What is the return value of the grid() method ? Try to write on two lines

self.secret_txt = Text(self, width = 35, height = 5, wrap = WORD)
self.secret_txt.grid(row = 3, column = 0, columnspan = 2, sticky = W)

Edited 5 Years Ago by Gribouillis: n/a

The two lines didn't work either.

Now I sound dumb, but how do I find out what the return value is?.

The two lines didn't work either.

Now I sound dumb, but how do I find out what the return value is?.

Your error message means that self.secret_txt is None, so what you can do is find out when this member becomes None. This can be done with a few prints in your program.

Edited 5 Years Ago by Gribouillis: n/a

The trouble is, it shouldn't become None at all..

Here is the whole code:

from tkinter import *

class Application(Frame):
    def __init__(self, master):
        super(Application, self).__init__(master)
        self.grid()
        self.create_widgets()
        
    def create_widgets(self):
        self.inst_lbl = Label(self, text = "Enter the password for the secret of longevity").grid(row = 0, column = 0, columnspan = 2, sticky = W)
        self.pw_lbl = Label(self, text = "Password: ").grid(row = 1, column = 0, sticky = W)
        self.pw_ent = Entry(self).grid(row = 1, column = 1, sticky = W)
        self.submit_bttn = Button(self, text = "Submit", command = self.reveal).grid(row = 2, column = 0, sticky = W)
        self.secret_txt = Text(self, width = 35, height = 5, wrap = WORD).grid(row = 3, column = 0, columnspan = 2, sticky = W)
        
        
    def reveal(self):
        contents = self.pw_ent.get()
        if contents == "secret":
            message = "Here's the secret to living to 100: live to 99 and then be VERY careful."
        else:
            message = "That wasn't the right password, I can let you know the secret."
        
        self.secret_txt.delete(0.0, END)
        self.secret_txt.insert(0.0, message)
        

root = Tk()
root.title("Secret of Longevity")
root.geometry("300x150")
app = Application(root)
root.mainloop()

As mentioned, I just changed 'WORD' to 'CHAR', and that's when the error began, and it didn't help to change it back.

The trouble is, it shouldn't become None at all..

Here is the whole code:

from tkinter import *

class Application(Frame):
    def __init__(self, master):
        super(Application, self).__init__(master)
        self.grid()
        self.create_widgets()
        
    def create_widgets(self):
        self.inst_lbl = Label(self, text = "Enter the password for the secret of longevity").grid(row = 0, column = 0, columnspan = 2, sticky = W)
        self.pw_lbl = Label(self, text = "Password: ").grid(row = 1, column = 0, sticky = W)
        self.pw_ent = Entry(self).grid(row = 1, column = 1, sticky = W)
        self.submit_bttn = Button(self, text = "Submit", command = self.reveal).grid(row = 2, column = 0, sticky = W)
        self.secret_txt = Text(self, width = 35, height = 5, wrap = WORD).grid(row = 3, column = 0, columnspan = 2, sticky = W)
        
        
    def reveal(self):
        contents = self.pw_ent.get()
        if contents == "secret":
            message = "Here's the secret to living to 100: live to 99 and then be VERY careful."
        else:
            message = "That wasn't the right password, I can let you know the secret."
        
        self.secret_txt.delete(0.0, END)
        self.secret_txt.insert(0.0, message)
        

root = Tk()
root.title("Secret of Longevity")
root.geometry("300x150")
app = Application(root)
root.mainloop()

As mentioned, I just changed 'WORD' to 'CHAR', and that's when the error began, and it didn't help to change it back.

As I said before, grid() returns None and for each of your subwidgets, you must use 2 lines, one to create the widget and the second line to call grid(). See my first post and compare carefully to your code.

I just finished a program

Well actually you copied the program out of the book, which with no offense to the author, isn't the greatest. I've found a large amount of the code in that book to be a bit buggy, or unclear. The way I got over that was to try to write codes that used the mechanics trying to be taught. Here, try this: write a program that takes a password and if the password is correct prints the password in a Text box, otherwise it prints the number of attempts so far in the Text box. That will be your own original code and it'll probably be easier to see where things go wrong in that as opposed to Michael Dawson's code.

I understand it now. Thanks for the help, and sorry I used up your time on this trifle matter.
I thought I could make on single line, instead of two:

self.secret_txt = Text(self, width = 35, height = 5, wrap = WORD).grid(row = 3, column = 0, columnspan = 2, sticky = W)

But could you then tell me why it works with:

self.submit_bttn = Button(self, text = "Submit", command = self.reveal).grid(row = 2, column = 0, sticky = W)

Apparently you need two lines with Text, but can do one line with Button.

You need to actually save the widget only if you refer to it later to change it, also some case it is necessary to store the widget somewhere so garbage collector does not collect it as rubbish. If you do grid together with creation, you should not assign the None anywhere (remove self.submit_bttn). Also spell variable names fully or do global search and replace to change abbreviations to full words in the end and test that code runs still.

To refer it later you can alternatively tag it by 'tag' parameter.

Edited 5 Years Ago by pyTony: n/a

I didn't quite understand your advice fully, but I guess I need more experience, and I can later use it for reference. So thank you!

This question has already been answered. Start a new discussion instead.