Tkinter not removing a Label widget - python

I am relatively new to this, but is anyone able to find out why errorLabel is not forgetting? I do not see the reason as to why this would be the case. All of the other widgets disappear, but not the errorLabel.
def checkLogin(root, username, password, userNameLabel, userNameEntry, passwordLabel, passwordEntry, loginButton):
print(gui.checkUser(username, password))
errorLabel = Label(root, text="")
errorLabel.pack()
if (gui.checkUser(username, password)):
userNameLabel.forget()
errorLabel.forget()
userNameEntry.forget()
passwordLabel.forget()
passwordEntry.forget()
loginButton.forget()
else:
errorLabel.config(text="Error, that is an incorrect username and/or password")
This is whole code
class gui:
def checkUser(username, password):
data = musicQuiz.getUsers()
for usernameDB, passwordDB in data:
if str(usernameDB) == str(username) and str(passwordDB) == str(password):
return True
return False
def checkLogin(root, username, password, userNameLabel, userNameEntry, passwordLabel, passwordEntry, loginButton):
print(gui.checkUser(username, password))
errorLabel = Label(root, text="")
errorLabel.pack()
if (gui.checkUser(username, password)):
userNameLabel.forget()
errorLabel.forget()
userNameEntry.forget()
passwordLabel.forget()
passwordEntry.forget()
loginButton.forget()
else:
errorLabel.config(text="Error, that is an incorrect username and/or password")
def login(root):
userNameLabel = Label(root, text="Username")
userNameEntry = Entry(root)
passwordLabel = Label(root, text="Password")
passwordEntry = Entry(root)
loginButton = Button(root, text = "Login!", command=lambda: gui.checkLogin(root, userNameEntry.get(), passwordEntry.get(), userNameLabel, userNameEntry, passwordLabel, passwordEntry, loginButton))
userNameLabel.pack()
userNameEntry.pack()
passwordLabel.pack()
passwordEntry.pack()
loginButton.pack()
def main():
musicQuiz.setupSQL()
root = Tk()
root.geometry("350x350")
gui.login(root)
root.mainloop()
if __name__ == "__main__":
gui.main()

Related

How can i get the value from the entry and inject into the init function parameter?

Here's the code:
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
import time
import sys
class TwitterBot:
def __init__(self, username, password):
self.username = username
self.password = password
entry_user = tk.Entry(lower_frame, bg="white", fg='black', bd=0)
#entry_user.insert(0, "Username")
#entry_user.bind("<Button-1>", del_value_user)
entry_user.pack(expand = "yes")
entry_pass = tk.Entry(lower_frame, bg="white", fg='black', bd=0)
#entry_pass.insert(0, "Password")
#entry_pass.bind("<Button-1>", del_value_pass)
entry_pass.pack(expand = "yes")
sasha = TwitterBot(entry_user.get(), entry_pass.get())
The entry never send the values I typed in into sasha = TwitterBot(entry, entry2)
Meaning I want that inside tkinter interface, I type in two entries that supposed to be username and password and when I execute the function those values get injected. I think the problem is that self.username and self.password are defined inside of the __init__ and so if those entries stay empty at the launch so i cant get them to inject. cause I can print my entry.get() values. I just cant make them replace the two first parameters of my __init__ function. Does anybody knows how to help?
Try this:
import tkinter as tk
class TwitterBot:
def __init__(self, username, password):
print("Username =", username, " Password =", password)
self.username = username
self.password = password
def create_bot(event=None):
sasha = TwitterBot(entry_user.get(), entry_pass.get())
print("started bot")
root = tk.Tk()
entry_user = tk.Entry(root, bg="white", fg='black', bd=0)
#entry_user.insert(0, "Username")
#entry_user.bind("<Button-1>", del_value_user)
entry_user.pack(expand=True)
# Log in if the user presses the Enter key:
entry_user.bind("<Return>", create_bot)
entry_pass = tk.Entry(root, bg="white", fg='black', bd=0)
#entry_pass.insert(0, "Password")
#entry_pass.bind("<Button-1>", del_value_pass)
entry_pass.pack(expand=True)
# Log in if the user presses the Enter key:
entry_pass.bind("<Return>", create_bot)
button = tk.Button(root, text="Log in", command=create_bot)
button.pack()
root.mainloop()
Your code wasn't working because as soon as your code created the entries it tried to get the data out of them (which obviously is an empty string) and created the TwitterBot object. To make it work you have to give the user time to enter their details in the entries by adding a button/binding to the user pressing the Enter key.
I created a button and placed it at the bottom of the window. When you click the button it calls create_bot which creates the TwitterBot object.
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
import time
import sys
import tkinter as tk
from tkinter import *
from tkmacosx import Button as button
class TwitterBot:
def __init__(self, username, password):
print("Username =", username, " Password =", password)
self.username = username
self.password = password
def open_br(self):
self.bot = webdriver.Firefox()
def end_br(self):
self.bot.quit()
def login(self):
bot = self.bot
bot.get("http://twitter.com/login/")
time.sleep(3)
email = bot.find_element_by_name("session[username_or_email]")
password = bot.find_element_by_name("session[password]")
email.clear()
password.clear()
email.send_keys(self.username)
password.send_keys(self.password)
password.send_keys(Keys.RETURN)
time.sleep(3)
def like_tweet(self, hashtag):
bot = self.bot
bot.get('https://twitter.com/search?q='+hashtag+'&src=typed_query')
time.sleep(3)
for i in range(1,8):
bot.execute_script('window.scrollTo(0,document.body.scrollHeight)')
time.sleep(2)
tweets = bot.find_elements_by_class_name('tweet')
tweetLinks = [i.get_attribute('href') for i in bot.find_elements_by_xpath("//a[#dir='auto']")]
filteredTweet = list(filter(lambda x: 'status' in x,tweetLinks))
print(filteredTweet)
for link in filteredTweet:
bot.get(link)
time.sleep(5)
if drop2_var.get() == "Retweet":
try:
bot.find_element_by_xpath("//div[#data-testid='retweet']").click()
bot.find_element_by_xpath("//div[#data-testid='retweetConfirm']").click()
time.sleep(3)
except Exception as ex:
time.sleep(10)
elif drop2_var.get() == "Likes":
bot.find_element_by_xpath("//div[#data-testid='like']").click()
time.sleep(3)
# def create_bot(event=None):
# sasha = TwitterBot(entry_user.get(), entry_pass.get())
# print("started bot")
sasha = TwitterBot("", "")
root = tk.Tk()
HEIGHT = 800
WIDTH = 400
#FUNCTIONS CLEARING ENTRY
def del_value(event): # note that you must include the event as an arg, even if you don't use it.
entry.delete(0, "end")
return None
def del_value_user(event): # note that you must include the event as an arg, even if you don't use it.
entry_user.delete(0, "end")
return None
def del_value_pass(event): # note that you must include the event as an arg, even if you don't use it.
entry_pass.delete(0, "end")
return None
def ex():
root.quit()
#PROGRAM SETTINGS
root.title("Social Bot")
root.minsize(400, 800)
#root.iconbitmap("/Users/sashakharoubi/Desktop/BOOTCAMP/Week 9/Day 2/image/logo.ico")
root.config(background="#66b3ff")
canvas = tk.Canvas(root, height= HEIGHT, width = WIDTH, bd=0, highlightthickness = 0)
canvas.pack()
# background_image = tk.PhotoImage(file = 'blue.png')
# background_label = tk.Label(root, image =background_image)
# background_label.place(x=0, y=0, relwidth=1, relheight=1)
#MAINFRAME
frame = tk.Frame(root, bg="#222f3e")
frame.place(relx = 0, rely = 0, relwidth = 1, relheight = 1)
#SUBPART FRAME
lower_frame = tk.Frame(root, bg="#E9E9E9", bd=0, highlightthickness = 0, relief="sunken")
#DROPDOWN MENU OPTIONS
OPTIONS = [
"Twitter",
"Instagram(not working)"
]
OPTIONS2 = [
"Likes",
"Retweet"
]
entry_txt = tk.Label(lower_frame, text="Welcome to Social Bot\n\nChoose an action to execute", font=("Montserrat", 15), bg="#E9E9E9", fg="black")
entry_txt.pack(expand = "yes")
#DROPDOWN MENU
drop_var = StringVar(lower_frame)
drop_var.set(OPTIONS[0])
drop2_var = StringVar(lower_frame)
drop2_var.set(OPTIONS2[0])
drop = OptionMenu(lower_frame, drop_var, *OPTIONS)
drop.config(fg="black")
drop.pack()
drop2 = OptionMenu(lower_frame, drop2_var, *OPTIONS2)
drop2.config(fg="black")
drop2.pack()
#ENTRIES
entry = tk.Entry(lower_frame, bg="white", fg='black', bd=0)
entry.insert(0, "-->Topic to like or retweet")
entry.bind("<Button-1>", del_value)
entry.pack(expand = "yes")
entry_user = tk.Entry(lower_frame, bg="white", fg='black', bd=0)
entry_user.insert(0, "----Type Your Username---")
entry_user.bind("<Button-1>", del_value_user)
entry_user.pack(expand = "yes")
#entry_user.bind("<Return>", create_bot)
entry_pass = tk.Entry(lower_frame, bg="white", fg='black', bd=0)
entry_pass.insert(0, "----Type Your Password---")
entry_pass.bind("<Button-1>", del_value_pass)
entry_pass.pack(expand = "yes")
#entry_pass.bind("<Return>", create_bot)
#BUTTONS
button_confirm = button(lower_frame, text="Confirm", bg="white", fg="black")
button_confirm.pack(pady=25, side = 'top')
button_open = button(lower_frame, text="Open Browser", bg="white", fg="black", command= sasha.open_br)
button_open.pack(pady=25, side = 'top')
button_log = button(lower_frame, text="LOG IN", bg='#54a0ff', fg="white", command =sasha.login, bd=0, highlightthickness = 0)
button_log.pack(pady=25, side = 'left')
button_launch = button(lower_frame, text="START", bg='#1dd1a1', fg="white", relief="flat", command = lambda: sasha.like_tweet(entry.get()), bd=0, highlightthickness = 0)
button_launch.pack(pady=25, side = 'right')
button_stop = button(lower_frame, text="STOP", bg="#ff6b6b", fg="white", command= sasha.end_br)
button_stop.pack(pady=25, side = 'bottom')
button_exit = button(lower_frame, text="Exit", bg ="white", fg="black", command= ex)
button_exit.pack(side = 'bottom')
lower_frame.place(relx = 0.1, rely = 0.1, relwidth=0.8, relheight=0.8)
#TITLE
label = tk.Label(frame, text="S O C I A L B O T", font=("Montserrat", 25), bg="white", fg="#222f3e")
label.pack(side="top", fill ="both")
root.mainloop()
v1 = browser.find_element_by_xpath("").text
try put .text at last of your code
then you can print or use v1 as a value

Is there a way to create new instances automatically?

As you can see, I can store passwords here.
I have to add a feature that I can register a new user. How do I do it so that I can create new instances when creating a new user?
import datetime
import getpass
class User:
def __init__(self, username, mail, date_of_birth, gender, password):
self.username = username
self.mail = mail
self.date_of_birth = datetime.datetime.strptime(date_of_birth, "%d.%m.%Y").date()
self.gender = gender
self.password = password
def get_username(self):
return self.username
def get_mail(self):
return self.mail
def get_date_of_birth(self):
return self.date_of_birth
def get_gender(self):
return self.gender
def get_password(self):
self.password
def get_date(self):
return self.date_of_birth
log = ""
def tries_left(self):
max_tries = 3
trie = 0
while trie <= max_tries:
print("wrong password!")
print("tries left " + str(max_tries - trie + 1))
trie +=1
pwrd = input("input password")
if pwrd != self.password:
pass
else:
self.login_or_register()
def login2(self):
global log
log = input("input your username: ")
if log == self.username:
pwrd = input("whats your password?")
if pwrd == self.password:
print("Logged in!")
self.add_password_orCheck_password()
else:
self.tries_left()
else:
print("wrong username!")
self.login2()
def login_or_register(self):
user_input = input("Login or Register: ")
if user_input == "login":
self.login2()
elif user_input == "register":
pass
else:
print("Try again!")
self.login_or_register()
def add_password(self):
global sitepassword
global Site
Site = input("Enter site name: ")
sitepassword = input("Enter password")
self.add_password_orCheck_password()
global passwords
passwords = {Site: sitepassword}
def check_passwords(self):
global passwords
global sitepassword
global Site
passwords = {Site: sitepassword}
which_password = input("Which sites password do you want to see?")
for Site in passwords:
if which_password in passwords:
print(sitepassword)
self.add_password_orCheck_password()
def add_password_orCheck_password(self):
add_new = input("Do you want to add a password or check passwords?")
if "add a password" in add_new:
self.add_password()
elif "check passwords" in add_new:
self.check_passwords()
Matt = User("Matterson", "matt#gmail.com", "21.12.1999" ,"male", "Password987")
session1 = Matt.login_or_register()
i wasnt thinking here is a better option:
users = {}
while True:
name = input('yourtexthere')
email = input('yourtexthere')
year = input('yourtexthere')
gender = input('yourtexthere')
password = input('yourtexthere') # here you will use getpass
users[f'{name}'] = User(name, email, year, gender, password)
however you can also store them in list but then you will have to access them by index and you may want to use the email as a key:
users[f'{email}'] = User(name, email, year, gender, password)
here is the code (refer to my comment) its not the cleanest one but it works, here you can try implementing your User class and making it as you need however you need experience in tkinter (this is just an example) hope it helps (it also creates the json file (if it is not already created) in this codes directory) (and I hope this aint against some guidlines):
from tkinter import *
from tkinter import messagebox
import json
all_user_pass = dict()
try:
with open('stored_data.json') as file:
data = json.load(file)
except:
with open('stored_data.json', 'w') as file:
json.dump(all_user_pass, file, indent=2)
with open('stored_data.json') as file:
data = json.load(file)
class MainWindow(Toplevel):
def __init__(self, parent):
self.parent = parent
Toplevel.__init__(self, parent)
self.x_tk = 310
self.y_tk = 100
self.win_h = int(self.winfo_screenheight()/2 - self.y_tk/2)
self.win_w = int(self.winfo_screenwidth()/2 - self.x_tk/2)
self.geometry(f"{str(self.x_tk)}x{str(self.y_tk)}+{str(self.win_w)}+{str(self.win_h)}")
self.title('Login')
self.protocol('WM_DELETE_WINDOW', self.quit)
self.username = Entry(self, bg="grey", bd=5, font="none 12 normal")
word_username = Label(self, text='Username:')
word_username.grid(row=0, column=0, sticky='w')
self.username.grid(row=0, column=1)
self.password = Entry(self, bg="grey", bd=5, font="none 12 normal")
word_password = Label(self, text='Password:')
word_password.grid(row=1, column=0, sticky='w')
self.password.grid(row=1, column=1)
login_button = Button(self, text='Login', command=self.login)
login_button.grid(row=2, column=0)
self.bind('<Return>', self.login)
signup_button = Button(self, text='Sign Up', command=self.open_signup)
signup_button.grid(row=2, column=2)
self.incorrect_user_or_pass = Label(self, text='Incorrect username or password!')
self.empty_user_or_pass = Label(self, text='Cannot be blank!')
def open_signup(self):
signupwindow = SignUpWindow(self)
signupwindow.focus_force()
signupwindow.withdraw
def login(self, event=None):
global data
existing_user = self.username.get()
user_pass = self.password.get()
self.incorrect_user_or_pass.place_forget()
if existing_user != '' and user_pass != '':
if existing_user in data and data[existing_user] == user_pass:
messagebox.showinfo('Successful Login', 'You have logged in successfully!', parent=self)
self.username.delete(0, 'end')
self.password.delete(0, 'end')
self.empty_user_or_pass.place_forget()
self.incorrect_user_or_pass.place_forget()
else:
self.username.delete(0, 'end')
self.password.delete(0, 'end')
self.empty_user_or_pass.place_forget()
self.incorrect_user_or_pass.place(x=60, y=65)
else:
self.empty_user_or_pass.place(x=90, y=65)
class SignUpWindow(Toplevel):
def __init__(self, parent):
self.parent = parent
Toplevel.__init__(self, parent)
self.x_tk = 310
self.y_tk = 100
self.win_h = int(self.parent.winfo_rooty() - 31)
self.win_w = int(self.parent.winfo_rootx() - 8)
self.geometry(f"{str(self.x_tk + 16)}x{str(self.y_tk + 39)}+{str(self.win_w)}+{str(self.win_h)}")
self.title('Signup')
self.bind('<FocusOut>', self.f_out_main)
self.bind('<Escape>', self.close)
self.update_idletasks()
self.overrideredirect(True)
self.config(bg='green')
Label(self, text='Signup', font='none 20 normal', bg='green', bd=5) .grid(row=0, column=0, columnspan=4)
self.username = Entry(self, bg="grey", bd=5, font="none 12 normal")
word_username = Label(self, text='Username:', bg='green')
word_username.grid(row=1, column=0, sticky='w')
self.username.grid(row=1, column=1)
self.username.bind('<FocusOut>', self.f_out)
self.password = Entry(self, bg="grey", bd=5, font="none 12 normal")
word_password = Label(self, text='Password:', bg='green')
word_password.grid(row=2, column=0, sticky='w')
self.password.grid(row=2, column=1)
self.password.bind('<FocusOut>', self.f_out)
cancel_button = Button(self, text='Cancel', command=self.cancel)
cancel_button.grid(row=3, column=0)
cancel_button.bind('<FocusOut>', self.f_out)
cancel_button.bind('<Return>', self.cancel)
signup_button = Button(self, text='Sign Up', command=self.signup)
signup_button.grid(row=3, column=2)
signup_button.bind('<FocusOut>', self.f_out)
self.bind('<Return>', self.signup)
self.user_taken = Label(self, text='Username already taken!', bg='green')
self.empty_user_or_pass = Label(self, text='Cannot be blank!', bg='green')
self.focus_list = []
def f_out(self, event=None):
self.focus_list.append('focus_out_of_widget')
def f_out_main(self, event=None):
self.focus_list.append('focus_out_of_window')
if len(self.focus_list) >= 2:
if self.focus_list[-2] == 'focus_out_of_window' and self.focus_list[-1] == 'focus_out_of_window':
self.close()
elif self.focus_list[0] == 'focus_out_of_window':
self.close()
def cancel(self, event=None):
self.destroy()
def signup(self, event=None):
global all_user_pass
global data
new_username = self.username.get()
new_password = self.password.get()
if new_username != '' and new_password != '':
if new_username not in data:
if new_username not in all_user_pass:
all_user_pass[new_username] = new_password
data.update(all_user_pass)
with open('stored_data.json', 'w') as f:
json.dump(data, f, indent=2)
self.username.delete(0, 'end')
self.password.delete(0, 'end')
self.user_taken.place_forget()
self.empty_user_or_pass.place_forget()
self.destroy()
else:
self.username.delete(0, 'end')
self.password.delete(0, 'end')
self.empty_user_or_pass.place_forget()
self.user_taken.place(x=90, y=110)
else:
self.username.delete(0, 'end')
self.password.delete(0, 'end')
self.empty_user_or_pass.place_forget()
self.user_taken.place(x=90, y=110)
else:
self.empty_user_or_pass.place(x=90, y=110)
def close(self, event=None):
self.parent.focus_set()
self.destroy()
root = Tk()
root.withdraw()
app = MainWindow(root)
app.mainloop()

Change password of login page with tkinter

I'm trying to make a login gui using tkinter, and I want a new window to open when I click on change password.
When the window opens it should prompt the user for a new password, and then change and store the password. Afterwards, it should login again using the changed password.
import tkinter as tk
import tkinter.messagebox as tm
class LoginFrame(tk.Frame):
storedPassword='password'
def __init__(self, master):
super().__init__(master)
#storedPassword='password'
self.label_username = tk.Label(self, text="Username")
self.label_password = tk.Label(self, text="Password")
self.entry_username = tk.Entry(self)
self.entry_password = tk.Entry(self)#, show="*") to help us see new password
self.label_username.grid(row=0)
self.label_password.grid(row=1)
self.entry_username.grid(row=0, column=1)
self.entry_password.grid(row=1, column=1)
self.logbtn = tk.Button(self, text="Login", command=self._login_btn_clicked)
self.logbtn.grid(columnspan=2)
newPassword = self.entry_password.get()
print(newPassword)
self.logbtn = tk.Button(self, text="change_password", command=self.change_password)
self.logbtn.grid(columnspan=2)
def change_password(self,newPassword):
self.new_password = tk.Label(self, text="new password")
self.entry_newpassword = tk.Entry(self)
self.storedPassword=newPassword
print(self.entry_newpassword.get())
def _login_btn_clicked(self):
username = self.entry_username.get()
password = self.entry_password.get()
if username == "admin":
if password == self.storedPassword:
tm.showinfo("Login info", "Welcome admin")
self.storedPassword=self.entry_password.get()
else:
tm.showerror("Login error", "Incorrect password")
else:
tm.showerror("Login error", "Incorrect username")
window= tk.Tk()
lf = LoginFrame(window)
#root = tk.Tk()
#newWindow= LoginFrame(root)
#root.mainloop()
window.mainloop()
Simply destroy the initial window first using window.destroy() and then create a new window in a function when it is called by the button. Continue adding entry widgets and labels as you know and get the new password and run another function to go back to initial page after using root.destroy() to remove change password window.
Here is a simple code showing what I just said:
from tkinter import *
from tkinter import messagebox
storedPassword = 'password'
def loginok(username,password):
global storedPassword
if username == "admin":
if password == storedPassword:
messagebox.showinfo("Login Successful!","Welcome Admin")
else:
messagebox.showerror("Login Failed!","Wrong Password")
else:
messagebox.showerror("Login Failed!","Wrong Username")
def cpass():
global window
window.destroy()
window = Tk()
Label(window,text="Enter new password:").pack()
passn = Entry(window,width=15)
passn.pack()
Button(window,text="OK",command=lambda:chgpass(passn.get())).pack()
window.mainloop()
def chgpass(newpass):
global window
global storedPassword
storedPassword = newpass
window.destroy()
login()
def login():
global window
window = Tk()
Label(window,text="Username:").pack()
usern = Entry(window,width=15)
usern.pack()
Label(window,text="Password:").pack()
passw = Entry(window,width=15,show="*")
passw.pack()
Button(window,text="Login",command=lambda:loginok(usern.get(),passw.get())).pack()
Button(window,text="Forgot",command=cpass).pack()
window.mainloop()
login()

How to close multiple Tkinter windows with one button

I am trying to build a python application. The first UGI is requesting the username and password. Then a second tk window pops up if login is successful with an okay button. Once then user press the okay button, both tk windows (the one requesting username and password and the login successful msg window) will disappear and the program continues to run.
I am very stuck with being able to press the okay button and close "both" windows. Any insights will be appreciated, thank you!
All the codes seem to be working fine. the command to execute function LoginSuccessful within the CheckLogin is able to execute the print("ANCD") but it doesn't close the two tk windows.
#import packages
import time
import openpyxl
from openpyxl import load_workbook
import tkinter as tk
from tkinter import *
import sys
def Function():
global user1
user1 = 'testing'
password1 = '0000'
def Login_form():
global username
global password
global rootA
rootA = Tk()
rootA.title('User Authentication')
msgbox1 = Label(rootA, text='Please Login\n')
msgbox1.grid(sticky=E)
username = Label(rootA, text='Username: ')
password = Label(rootA, text='Password: ')
username.grid(row=1, sticky=W)
password.grid(row=2, sticky=W)
username = Entry(rootA)
password = Entry(rootA, show='*')
username.grid(row=1, column=1)
password.grid(row=2, column=1)
login_btn = Button(rootA, text='Login', command=CheckLogin)
exit_btn=Button(rootA, text='Exit',command=sys.exit)
login_btn.grid(row=4, column=1)
exit_btn.grid(row=4, column=2)
rootA.mainloop()
def CheckLogin():
if username.get() == user1 and password.get() == password1:
rootA = Tk()
rootA.title('Authentication Cehck')
rootA.geometry('150x100') # Makes the window a certain size
rlbl = Label(rootA, text='\n Logged In')
okay_btn=Button(rootA, text='Okay',command=LoginSuccessful)
okay_btn.pack()
#LoginSuccessful()
else:
r = Tk()
r.title('Authentication Cehck')
r.geometry('150x160')
rlbl = Label(r, text='\n Invalid Login')
rlbl.pack()
okay_btn=Button(r, text='Try Again',command=r.destroy)
okay_btn.pack()
exit_btn=Button(r, text='Exit',command=sys.exit)
exit_btn.pack()
#r.mainloop()
def LoginSuccessful ():
rootA.destroy
print("ANCD")
def Insert_Rows():
for rows in range (len(All_Users_Sheet)):
if rows == 0:
rows +1
continue
if All_Users_Sheet[rows][10].value == None:
break
else:
print(All_Users_Sheet[rows][10].value)
print(type(All_Users_Sheet[rows][10].value))
Login_form()
Function()
Is there any way that after checking the username and password, if it's correct, close all tk windows by pressing a button and continue running the remaining tasks?
You should only create one instance of Tk. If you needed additional window, use Toplevel instead.
def CheckLogin():
if username.get() == user1 and password.get() == password1:
rootA = Toplevel()
rootA.title('Authentication Check')
...
else:
r = Toplevel()
...
i got one solution.
from tkinter import *
global user1
user1 = 'testing'
password1 = '0000'
def combine_funcs(*funcs):
def combined_func(*args, **kwargs):
for f in funcs:
f(*args, **kwargs)
return combined_func
def Login_form():
global username
global password
global rootA
rootA = Tk()
rootA.title('User Authentication')
msgbox1 = Label(rootA, text='Please Login\n')
msgbox1.grid(sticky=E)
username = Label(rootA, text='Username: ')
password = Label(rootA, text='Password: ')
username.grid(row=1, sticky=W)
password.grid(row=2, sticky=W)
username = Entry(rootA)
password = Entry(rootA, show='*')
username.grid(row=1, column=1)
password.grid(row=2, column=1)
login_btn = Button(rootA, text='Login', command=CheckLogin)
exit_btn=Button(rootA, text='Exit',command=rootA.destroy)
login_btn.grid(row=4, column=1)
exit_btn.grid(row=4, column=2)
rootA.mainloop()
def CheckLogin():
global rootA
if username.get() == user1 and password.get() == password1:
rootA = Tk()
rootA.title('Authentication Cehck')
rootA.geometry('150x100') # Makes the window a certain size
rlbl = Label(rootA, text='\n Logged In')
okay_btn=Button(rootA, text='Okay',command=LoginSuccessful)
okay_btn.pack()
#LoginSuccessful()
else:
r = Tk()
r.title('Authentication Cehck')
r.geometry('150x160')
rlbl = Label(r, text='\n Invalid Login')
rlbl.pack()
okay_btn=Button(r, text='Try Again',command=r.destroy)
okay_btn.pack()
exit_btn=Button(r, text='Exit',command= combine_funcs(rootA.destroy, r.destroy))
exit_btn.pack()
#r.mainloop()
def LoginSuccessful ():
rootA.destroy
print("ANCD")
def Insert_Rows():
for rows in range (len(All_Users_Sheet)):
if rows == 0:
rows +1
continue
if All_Users_Sheet[rows][10].value == None:
break
else:
print(All_Users_Sheet[rows][10].value)
print(type(All_Users_Sheet[rows][10].value))
Login_form()
please dont't ask about def combine_funcs(*funcs):
def combined_func(*args, **kwargs):
for f in funcs:
f(*args, **kwargs)
return combined_func
,it just solves the problem

Python Tkinter error: "Label has no __call__method"

Im trying to create a Python tkinter login registeration but running into a small issue.
The error message is:
self.Label_Name = Label(top, text="What is your username: ")
AttributeError: Label instance has no __call__ method
Please can you proof read my code:
from Tkinter import *
class Register:
def __init__(self, parent):
top = self.top = Toplevel(parent)
# Variables to store the entries
self.VarEntUser = StringVar()
self.VarEntPass = StringVar()
self.VarEntRetype = StringVar()
self.Label_Name = Label(top, text="What is your username: ")
self.Label_Password = Label(top, text="Enter a password: ")
self.Label_Retype = Label(top, text="Retype Password: ")
# Entry fields for the user to enter there details
self.Ent_Name = Entry(top, textvariable=self.VarEntUser)
self.Ent_Password = Entry(top, textvariable=self.VarEntPass)
self.Ent_Retype = Entry(top, textvariable=self.VarEntRetype)
# Puts all the fields ^, into the window
self.Label_Name.grid(row=0, sticky=W)
self.Label_Password.grid(row=1, sticky=W)
self.Label_Retype.grid(row=2, sticky=W)
self.Ent_Password.grid(row=1, column=1)
self.Ent_Retype.grid(row=2, column=1)
self.Ent_Name.grid(row=0, column=2)
# Run the RegisterCheck function
# submit button which Checks the Entered details then writes the user and pass to a .txt file
self.MySubmitButton = Button(top, text='Submit', command=RegisterCheck)
self.MySubmitButton.pack()
self.U = raw_input(self.VarEntUser.get())
self.P = raw_input(self.VarEntPass.get())
self.R = raw_input(self.VarEntRetype.get())
class LogIn:
def __init__(self, parent):
top = self.top = Toplevel(parent)
self.a = StringVar()
self.b = StringVar()
self.Label_Log_User1 = Label(top, text='Username:')
self.Label_Log_Pass = Label(top, text='Password: ')
self.Ent_User_Log = Entry(top, textvariable=self.a)
self.Ent_Pass_Log = Entry(top, textvariable=self.b)
self.Label_Log_User1.grid(row=1)
self.Pass_Log.grid(row=2)
self.EntUserLog.grid(row=1, column=1)
self.EntPassLog.grid(row=2, column=1)
self.User = raw_input(self.EntUserLog.get())
self.Pass = raw_input(self.EntUserLog.get())
# runs the 'LoginCheck' function
self.LogInButton = Button(top, text="Log In", command=LogInCheck)
self.LogInButton.pack()
def LogInCheck(self):
# Checks if the fields are blanking displaying an error
if len(self.User) <= 0 and len(self.Pass) <= 0:
print "Please fill in all fields."
else:
pass
# Checks to see if the user and pass have been created
if self.User in 'username.txt' and self.Pass in 'password':
print 'You are now logged in!'
else:
print "Log in Failed"
def RegisterCheck(self):
# Checks if the fields are blank
if len(self.P) <= 0 and len(self.U) <= 0:
print "Please fill out all fields."
else:
pass
# Check is the password and the retype match
if self.P == self.R:
pass
else:
print "Passwords do not match"
# After registering write the user and pass to a .txt file
with open('username.txt', 'a') as fout:
fout.write(self.U + '\n')
with open('password.txt', 'a') as fout:
fout.write(self.P + '\n')
# Depending on what the user chooses, either log in or register than opens the specific window
def launch_Register():
inputDialog = Register(root)
root.wait_window(inputDialog.top)
def launch_LogIn():
inputdialog2 = LogIn(root)
root.wait_window(inputdialog2.top)
root = Tk()
label = Label(root, text='Choose an option')
label.pack()
loginB = Button(root, text='Log In', command=launch_LogIn)
loginB.pack()
registerB = Button(root, text='Register', command=launch_Register)
registerB.pack()
root.mainloop()
The problem is that in this line
Label = Label(root, text='Choose an option')
you define a Label called Label, thus shadowing the Label constructor. Then, then you create the several labels in your Register and Login classes (triggered by those two buttons), the name Label is no longer bound to the constructor, but to that specific label.
Change the name of the label, then it should work. Also, I would advise you to use lower-case names for variables and methods. This alone might help prevent many such errors.
root = Tk()
label = Label(root, text='Choose an option')
label.pack()
loginB = Button(root, text='Log In', command=launch_LogIn)
loginB.pack()
registerB = Button(root, text='Register', command=launch_Register)
registerB.pack()
root.mainloop()
Note that there are a few many more problems with your code:
StringVar a and b should probably be self.a and self.b
You are trying to use raw_input to get the user input in the Entry widgets; this is wrong! Instead, just read the value of the variables to get the values, e.g. instead of self.User, use self.a.get()
do not mix grid and pack layout
if self.User in 'username.txt' will not check whether that name is in that file
loginCheck and registerCheck should be methods of the respective class
Once I'm at it, here's (part of) my version of your code, to help you getting started:
class Register:
def __init__(self, parent):
top = self.top = Toplevel(parent)
self.var_user = StringVar()
self.var_pass = StringVar()
self.var_retype = StringVar()
Label(top, text="What is your username: ").grid(row=0, sticky=W)
Label(top, text="Enter a password: ").grid(row=1, sticky=W)
Label(top, text="Retype Password: ").grid(row=2, sticky=W)
Entry(top, textvariable=self.var_user).grid(row=0, column=1)
Entry(top, textvariable=self.var_pass).grid(row=1, column=1)
Entry(top, textvariable=self.var_retype).grid(row=2, column=1)
Button(top, text='Submit', command=self.registerCheck).grid(row=3)
def registerCheck(self):
u, p, r = self.var_user.get(), self.var_pass.get(), self.var_retype.get()
if p and u:
if p == r:
logins[u] = p
else:
print "Passwords do not match"
else:
print "Please fill out all fields."
class LogIn:
# analogeous to Register; try to figure this out xourself
def launch_Register():
inputDialog = Register(root)
root.wait_window(inputDialog.top)
def launch_LogIn():
inputDialog = LogIn(root)
root.wait_window(inputDialog.top)
logins = {}
root = Tk()
Label(root, text='Choose an option').pack()
Button(root, text='Log In', command=launch_LogIn).pack()
Button(root, text='Register', command=launch_Register).pack()
root.mainloop()
Note that I changed the login "database" from files to a dictionary to keep things simple and to focus on the Tkinter problems. Of course, neither a simple dictionary nor a plain-text file is an appropriate way to store login information.
Also, I put the creation and the layout of the GUI widgets on one line. In this case this is possible since we do not need a reference to those widgets, but beware never to do e.g. self.label = Label(...).grid(...), as this will bind self.label to the result of grid, and not to the actual Label.
Finally, this will still print all the messages to the standard output. Instead, you should add another Label for that, or open a message dialogue, but this is left as an excercise to the reader...

Categories