no attribute to destroy

60 views Asked by At

I have two functions the top_signup_click and the top_login_click. The top_signup_click function is below the top_login_click function. The top_login_click function doesn't work because the_top_signup_click function is below it. To fix that issue I'll have to put the top_signup_click above the top_login_click function, which does solve the issue but it also creates another issue, now the top_signup_click function doesn't work. For both functions to work they both have to be below each other, but I don't think that's possible. If you know any other ways to do this please help. I tried using global functions to fix it but it didn't work.

import tkinter as tk
import tkinter.font as font
import tkinter.messagebox 

signup_button = None
root = tk.Tk()
root.geometry('360x460')

#login stuff
def login_click():
    readfile = open("emails.txt", "r")
    lines = readfile.readlines()
    isIN = False
    for line in lines:
        
        if f'{entry.get()}, {entry1.get()}' in line:
            isIN = True
    if not isIN:
        tk.messagebox.showinfo(message ="You got your email/password wrong, are you sure you signed in?")
    else:
        tk.messagebox.showinfo(message ="You hacker, the email/password is correct") 

def signup_click():
    file = open("emails.txt","a")
    file.write (entry.get())
    file.write(f', {entry1.get()}\n')

def top_login_click():
    global signup_button
    signup_button.destroy()
    login_button = tk.Button(root, text="Login", bg='royalblue', fg='white', command = login_click, width = 15, height = 2)
    login_button['font'] = button_font
    login_button.place(x=88,y=330)
#when the top sign up button is pressed

def top_signup_click():
    global login_button
    login_button.destroy()
    signup_button = tk.Button(root, text="Sign-Up", bg='royalblue', fg='white', command = login_click, width = 15, height = 2)
    signup_button['font'] = button_font
    signup_button.place(x=88,y=330)



top_font = font.Font(family='Helvetica', size=14, weight='bold')
label_font = font.Font(family='Helvetica', size=20)
button_font = font.Font(family='Helvetica', size=14, weight='bold')

top_login_button = tk.Button(root,text = 'Login',width = 15, height = 3, command = top_login_click)
top_login_button.place(x=0,y=0)
top_login_button['font'] = top_font


top_signup_button = tk.Button(root,text = 'Sign-Up',width = 15, height = 3, command = top_signup_click)
top_signup_button.place(x=180,y=0)
top_signup_button['font'] = top_font


username_label = tk.Label(root, text = 'Username: ' )
username_label['font'] =label_font
username_label.place(x=120,y=120)

entry = tk.Entry(root, width = 40)
entry.place(x=65,y=170, height = 30)

password_label = tk.Label(root, text = 'Password: ' )
password_label['font'] =label_font
password_label.place(x=120,y=230)

entry1 = tk.Entry(root, width = 40)
entry1.place(x=65,y=280, height = 30)

login_button = tk.Button(root, text="Login", bg='royalblue', fg='white', command = login_click, width = 15, height = 2)
login_button['font'] = button_font
login_button.place(x=88,y=330)



root.mainloop()

The top_login_click function is on line 29-34 and the top_signup_click function is on line 37-42. Thanks in advance.

1

There are 1 answers

4
P S Solanki On BEST ANSWER

I wanted to comment this but seems like I don't have enough reputation but here is what I think.

You have set the variable signup_button = None right below the import statements so signup_button is not really a tk.Button object, instead it's a NoneType variable.

So just remove that statement and create

signup_button = tk.Button(<args here>)

and You should be good.

and try using place_forget() instead of destroy() IFF destroy doesn't work for you.

Edit: What I also think in your case that you may not really need to destroy the signup_up button because you haven't created one yet. Think about it this way (based on the GUI that comes up on running your code) - on the landing screen of your app (the first screen that comes up), you have a login form with two entry boxes for email & pword and a login button, along with two more buttons called top_login_button and top_signup_button. So You DO NOT have a signup_button as of now (and according to your code signup_button = None it's not a button). So if a user now clicks on the top_login_button, the statement signup_button.destroy() will look for widget with the name signup_button (which is set to None by you) so it raises the error.

You code will run fine in a case where user clicks on top_signup_button before clicking on top_login_button because in that case the signup_button will be actually set to be a tk.Button object.