I'm trying to build a gui that creates a password and i've got as far as generating the password and making it appear in a label. However when the button is clicked multiple times it appears the old password doesnt dissapear, it just overlays on top. I'm also getting an error that i cant seem to rectify, although it doesnt seem to affect the gui.
The code so far is:
from tkinter import *
import random
myGui = Tk()
myGui.geometry('300x200+700+250')
myGui.title('Password Generator')
def passwordgen():
password = ''
for i in range(8):
##----runs the for loop 8 times
if (i == 0) or (i == 4):
password = password + chr(random.randint(97, 122))
if (i == 1) or (i == 5):
password = password + chr(random.randint(65, 90))
if (i == 2) or (i == 6):
password = password + chr(random.randint(48, 57))
if (i == 3) or (i == 7):
password = password + chr(random.randint(33, 47))
passLabel = Label(myGui, text=password)
passLabel.grid(row=0, column=1, sticky=E)
genPassBtn = Button(myGui, text="Generate Password", command=passwordgen)
genPassBtn.bind("<Button-1>", passwordgen)
genPassBtn.grid(row=0, column=0, sticky=W)
myGui.mainloop()
The error i receive is:
return self.func(*args)
TypeError: passwordgen() takes 0 positional arguments but 1 was given
The outcome i am hoping to achieve is to create a gui that generates a password, generates a hash value for generated password, checks the password strength, loads the generated hash to a text file and then can verify the password against stored hashes.
Further on now and from advice received i have amended the code and added extra to check the strength. The code now looks like this:
from tkinter import *
import random
myGui = Tk()
myGui.geometry('300x200+700+250')
myGui.title('Password Generator')
def passwordgen():
password = ''
for i in range(8):
##----runs the for loop 8 times
if (i == 0) or (i == 4):
password = password + chr(random.randint(97, 122))
if (i == 1) or (i == 5):
password = password + chr(random.randint(65, 90))
if (i == 2) or (i == 6):
password = password + chr(random.randint(48, 57))
if (i == 3) or (i == 7):
password = password + chr(random.randint(33, 47))
strPassword.set(password)
def checkPassword():
strength = ['Blank', 'Very Weak', 'Weak', 'Medium', 'Strong', 'Very Strong']
score = 1
password = strPassword.get()
if len(password) < 1:
return strength[0]
if len(password) < 4:
return strength[1]
if len(password) >= 8:
score += 1
if re.search('[0-9]', password):
score += 1
if re.search('[a-z]', password) and re.search('[A-Z]', password):
score += 1
if re.search('.', password):
score += 1
passwordStrength.set(strength[score])
genPassBtn = Button(myGui, text="Generate Password", command=passwordgen)
strPassword = StringVar()
lblPassword = Label(myGui, textvariable=strPassword)
lblPassword.grid(row=0, column=1, sticky=W)
genPassBtn.grid(row=0, column=0, sticky=W)
passwordStrength = StringVar()
checkStrBtn = Button(myGui, text="Check Strength", command=checkPassword)
checkStrBtn.grid(row=1, column=0)
checkStrLab = Label(myGui, textvariable=passwordStrength)
checkStrLab.grid(row=1, column=1)
myGui.mainloop()
Try this example.
from tkinter import *
import random
myGui = Tk()
myGui.geometry('300x200+700+250')
myGui.title('Password Generator')
def passwordgen():
password = ''
for i in range(8):
##----runs the for loop 8 times
if (i == 0) or (i == 4):
password = password + chr(random.randint(97, 122))
if (i == 1) or (i == 5):
password = password + chr(random.randint(65, 90))
if (i == 2) or (i == 6):
password = password + chr(random.randint(48, 57))
if (i == 3) or (i == 7):
password = password + chr(random.randint(33, 47))
strPassword.set(password)
genPassBtn = Button(myGui, text="Generate Password", command=passwordgen)
strPassword = StringVar()
lblPassword = Label(myGui, textvariable=strPassword)
lblPassword.grid(row=0,column=1, sticky=W)
genPassBtn.grid(row=0, column=0, sticky=W)
myGui.mainloop()
Here's what I've done
Rather than creating a new label each time, I change the text of a label using the StringVar called strPassword.
You don't need to bind a button to a click to call a function, using Button(... , command=myFunction) does this already.
Related
I created a password generator, which creates random passwords out of symbols, numbers and characters. There I have an input, where the user must enter a value and it has to be numeric. So I tried to solve this with elif. But, even when expected number (int) is entered, the loop is still stuck at elif. Here my code:
def PasswordGenerationFunc():
password = None
passwordLength = inputPasswordLength.get()
userName = inputUsername.get()
if len(passwordLength) == 0:
ResultDisplay.configure(text="Length of password is mandatory.", fg="red")
elif type(passwordLength) != int:
ResultDisplay.configure(text="Only digits are allowed." + passwordLength, fg="red")
else:
passwordLength = int(passwordLength)
if passwordLength > maxPasswordLength:
ResultDisplay.configure(text="The limit of password length are 20 characters.", fg="red")
else:
if userName != "":
password = "".join([random.choice(passwordConstructor) for i in range(passwordLength)])
ResultDisplay.configure(text="Generated password for " + userName + " is:\n" + password, fg="white")
else:
password = "".join([random.choice(passwordConstructor) for i in range(passwordLength)])
ResultDisplay.configure(text="Generated password is: \n" + password, fg="white")
In
ResultDisplay.configure(text="Only digits are allowed." + passwordLength, fg="red")
I print out passwordLength to check if wrong values were passed, but was not the case. I am so into the loop, I might ignoring some logic.
Expected behaviour:
User enters letters, loop stops at elif. User enters digits, loop enters else condition.
Now:
User enters digits, loop still stops at elif.
Here my full code, so you might understand it better:
# This is a small tool to generate passwords
# IMPORTS
from datetime import datetime
import random
from tkinter import *
# VARIABLES
date = datetime.now()
dateFormat = str(date.strftime("%d-%m-%Y %H:%M:%S"))
lowerCase = "abcdefghijklmnopqrstuvwxyz"
upperCase = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
numbers = "0123456789"
symbols = "!?%&##+*"
passwordConstructor = lowerCase + upperCase + numbers + symbols
maxPasswordLength: int = 20
bgColor_1 = "black"
# MAKE OUTPUT SELECTABLE
# GENERATE PASSWORD FUNCTION
def PasswordGenerationFunc():
password = None
passwordLength = inputPasswordLength.get()
userName = inputUsername.get()
if len(passwordLength) == 0:
ResultDisplay.configure(text="Length of password is mandatory.", fg="red")
#elif type(passwordLength) != int:
elif isinstance(passwordLength, int):
ResultDisplay.configure(text="Only digits are allowed.", fg="red")
else:
passwordLength = int(passwordLength)
if passwordLength > maxPasswordLength:
ResultDisplay.configure(text="The limit of password length are 20 characters.", fg="red")
else:
if userName != "":
password = "".join([random.choice(passwordConstructor) for i in range(passwordLength)])
ResultDisplay.configure(text="Generated password for " + userName + " is:\n" + password, fg="white")
else:
password = "".join([random.choice(passwordConstructor) for i in range(passwordLength)])
ResultDisplay.configure(text="Generated password is: \n" + password, fg="white")
# SCREEN
screen = Tk()
screen.geometry("450x400")
screen.configure(bg="black")
screen.title("PASSWORD GENERATOR")
# TITLE
Title = Label(screen, text="PASSWORD GENERATOR", font=("Arial Bold", 18), fg="green")
Title.configure(bg="black")
Title.pack(pady=20)
# MAIN FRAME
MainFrame = Frame(screen)
MainFrame.configure(bg="black")
MainFrame.pack(pady=5)
# INPUT USERNAME
usernameLabel = Label(MainFrame, text="Please enter username:", font=("Arial Bold", 14))
usernameLabel.configure(bg="black")
usernameLabel.pack()
inputUsername = Entry(MainFrame, font=("Arial Bold", 12))
inputUsername.pack()
# INPUT PASSWORD LENGTH
passwordLengthLabel = Label(MainFrame, text="Please enter length of password:", font=("Arial Bold", 14))
passwordLengthLabel.configure(bg="black")
passwordLengthLabel.pack()
inputPasswordLength = Entry(MainFrame, font=("Arial Bold", 12))
inputPasswordLength.pack()
# GENERATE BUTTON
GenerateBtn = Button(MainFrame, text="GENERATE", font=("Arial", 14), command=PasswordGenerationFunc, bg="black")
GenerateBtn.pack(pady=10)
# DISPLAY RESULT
ResultDisplay = Label(MainFrame, text="", font=("Arial", 14))
ResultDisplay.configure(bg="black")
ResultDisplay.pack(pady=15)
# COPY TO CLIPBOARD BUTTON
#CopyBtn = Button(MainFrame, text="COPY", font=("Arial", 14), bg="black")
#CopyBtn.clipboard_append(password)
#CopyBtn.pack(pady=10)
# WINDOW
screen.mainloop()
First, convert the input to int.
try:
passwordLength = int(input("Your message "))
except ValueError:
print(f"Input is not a valid integer. Please try again.")
Modify the if conditions for an integer input as follows:
if passwordLength == 0:
pass # your output here
else:
pass # your logic to generate a password
To compare objects and its datatype use isinstance(object, type):
isinstance(3, int) ===> True
isinstance(3, str) ===> False
I am having trouble getting these checks to work. it is for a password change program using tkinter. The aim is to make sure the password has both capital and lowercase letters, and is more than 8 characters long. the code always outputs false, even when the password should pass all the checks.
def check_password():
global oldpassword_entry
oldpasswordcheck= oldpassword_entry.get()
global newpassword_entry
newpasswordcheck= newpassword_entry.get()
global newpasswordconfirmed_entry
newpasswordconfirmedcheck= newpasswordconfirmed_entry.get()
if oldpasswordcheck == oldpassword:
if (any(x.isupper() for x in newpasswordcheck) and any(x.islower() for x in newpasswordcheck) and any(x.isdigit() for x in newpasswordcheck) and len(s) >= 8):
if newpasswordcheck == newpasswordconfirmedcheck:
passwordtrue = 'true'
print(passwordtrue)
showoldpasswordchange_label.configure(text=newpasswordconfirmedcheck)
else:
passwordtrue = 'false'
print(passwordtrue)
else:
passwordtrue = 'false'
print(passwordtrue)
else:
passwordtrue = 'false'
print(passwordtrue)
okaybutton_button = ttk.Button(root, text= "Okay", width= 20, command= check_password)
the variables at the start of the function come from the entries here:
showoldpassword_label = tk.Label(root, text = 'Current Password: ', font=('calibre',10, 'bold'))
showoldpasswordchange_label = tk.Label(root, text = 'PasswordExample', font=('calibre',10, 'bold'))
oldpassword_label = tk.Label(root, text = 'Old Password: ', font=('calibre',10, 'bold'))
oldpassword_entry = tk.Entry(root, font=('calibre',10,'normal'), show = '*')
newpassword_label = tk.Label(root, text = 'New Password: ', font=('calibre',10, 'bold'))
newpassword_entry = tk.Entry(root, font=('calibre',10,'normal'), show = '*')
newpasswordconfirmed_label = tk.Label(root, text = 'Confirm Password: ', font=('calibre',10, 'bold'))
newpasswordconfirmed_entry = tk.Entry(root, font=('calibre',10,'normal'), show = '*')
when the code is run it makes this box:
What is s in if (any(x.isupper() for x in newpasswordcheck) and any(x.islower() for x in newpasswordcheck) and any(x.isdigit() for x in newpasswordcheck) and len(s) >= 8):
Maybe just swap s for newpasswordcheck?
The code otherwise looks right to me, i havn't tried it though just read it and im missing s and oldpassword which i'm guessing is the current password as a string?
I'm trying to make my scoring system work. it keeps forgetting after I have changed the score once I go back into the class as it is set as 0. How would I change this so the score changes as appropriate?
code:
import random
from tkinter import *
class TimesTableGUI:
def __init__(self, parent, score = 0):
self.score = score
#chooses a random number
num1 = random.randint(1,10)
num2 = random.randint(1,10)
self.answer = num1 * num2
#making labels
entry_label = Label(parent, text = str(num1) + " * " + str(num2))
entry_label.grid(row = 0, column = 0)
self.e1 = Entry(parent, width = 5)
self.e1.grid(row = 0, column = 1)
b1 = Button(parent, text = "Check Answer", command = self.check_answer)
b1.grid(row = 1, column = 0)
b2 = Button(parent, text = "Next", command = self.new_question)
b2.grid(row = 1, column = 1)
self.b1_output = Label(parent, text = self.score)
self.b1_output.grid(row = 2, column = 0)
def check_answer(self): #callback for Check Answer button
#check if users gets correct answer
f = int(self.e1.get())
if f == self.answer:
self.score +=1
self.b1_output.configure(text = self.score)
else:
self.b1_output.configure(text = self.score)
def new_question(self): #callback for Next button to next question
self.b1_output.configure(text = " ")
radiobuttons = TimesTableGUI(root) #restarts the class for new question
if __name__ == "__main__":
root = Tk()
root.title("Task 3")
radiobuttons = TimesTableGUI(root)
root.mainloop()
Try this:
import random
from tkinter import *
class TimesTableGUI:
def __init__(self, parent, score=0):
self.score = score
self.master = parent
self.ask_new_question()
self.b1_output = Label(parent, text="Score = %i" % self.score)
self.b1_output.grid(row=2, column=1)
def ask_new_question(self):
self.question_frame = Frame(self.master)
self.question_frame.grid(row=1, column=1)
#chooses a random number
num1 = random.randint(1, 10)
num2 = random.randint(1, 10)
self.answer = num1 * num2
#making labels
entry_label = Label(self.question_frame, text="%i*%i" % (num1, num2))
entry_label.grid(row=0, column=0)
self.e1 = Entry(self.question_frame, width=5)
self.e1.grid(row=0, column=1)
self.check_answer_btn = Button(self.question_frame, text="Check Answer",
command=self.check_answer)
self.check_answer_btn.grid(row=1, column=0)
b2 = Button(self.question_frame, text="Next",
command=self.new_question)
b2.grid(row=1, column=1)
def check_answer(self):
user_answer = int(self.e1.get())
if user_answer == self.answer:
self.score += 1
self.b1_output.configure(text="Score = %i" % self.score)
# So the user can't submit more than 1 correct answer
self.check_answer_btn.config(state="disabled")
def new_question(self):
# Remove the frame (and all of its children)
self.question_frame.destroy()
# Display the new question
self.ask_new_question()
if __name__ == "__main__":
root = Tk()
root.title("Task 3")
radiobuttons = TimesTableGUI(root)
root.mainloop()
I moved all of the widgets that are for the question inside a frame. The frame gets destroyed and recreated each time a new question needs to be displayed. I also made sure the user can't just keep clicking on Check Answer after they got the correct answer already (for that question).
The problem is that when you you call radiobuttons = TimesTableGUI(root) score is getting reset too.
Quick solution: pass score when you call radiobuttons = TimesTableGUI(root, score=self.score) in new_question
Better solution: create a method that reset GUI without reinitialize the entire class.
This question already has answers here:
Why is my Button's command executed immediately when I create the Button, and not when I click it? [duplicate]
(5 answers)
Closed 1 year ago.
The goal of this code is to create a functioning login screen. However, in the process of creating the "create_account()" and implementing it, I noticed that for some reason it triggers as soon as the program runs. Not only that but when the button that the function is linked to is clicked, nothing seems to happen. What gives?
from tkinter import *
counter = 0
def login():
user = txt.get()
pwd = txt2.get()
if user in users:
if pwd == users[user]:
lbl3.config(text="Login successful")
else:
lbl3.config(text="Invalid username or password")
else:
lbl3.config(text="Invalid username or password")
user = txt.get()
pwd = txt2.get()
certificate = 0
if user in users:
if pwd == users[user]:
lbl3.config(text="Login successful")
else:
lbl3.config(text="Invalid username or password")
else:
lbl3.config(text="Invalid username or password")
def up(string):
for x in string:
if(x.upper()):
return True
else:
return False
def low(string):
for x in string:
if(x.lower()):
return True
else:
return False
def length(string):
if(len(string) > 8 and len(string) < 15):
return True
else:
return False
def whitespace(string):
for x in string:
if(x.isspace()):
return False
else:
return True
def number(string):
for x in string:
if(x.isdigit()):
return True
else:
return False
def alphanumberic(string):
for x in string:
if(x.isalnum()):
return False
else:
return True
def valid_password(string):
up(string)
low(string)
length(string)
whitespace(string)
number(string)
alphanumberic(string)
if(string==("BigCodez4life!")):
return True
def valid_username(string):
up(string)
low(string)
whitespace(string)
number(string)
alphanumberic(string)
if(string==("BigCodez4life!")):
return True
if(length(string) == True and whitespace(string) == False and number(string) == True and alphanumberic(string) == False and up(string) == True and low(string) == True):
return True
else:
return False
def create_account():
username = txt.get()
password = txt2.get()
if username != "" and valid_username(username) == True and valid_password(password) == True:
lbl3.config(text="Account Created")
else:
lbl3.config(text="Invalid username or password")
window = Tk()
window.title("Login Window")
window.geometry("480x270")
lbl = Label(window, text="Username")
lbl.grid(column=0, row=0)
lbl2 = Label(window, text="Password")
lbl2.grid(column=0, row=1)
lbl3 = Label(window, text="Hidden")
lbl3.grid(column=1, row=10)
lbl3['foreground']="red"
lbl3['width']=30
txt = Entry(window,width=15)
txt.grid(column=1, row=0)
txt2 = Entry(window,width=15,show="*")
txt2.grid(column=1, row=1)
btn = Button(window, text="Login", command=login)
btn.grid(column=2, row=7)
btn2 = Button(window, text="Create Account", command=create_account())
btn2.grid(column=0, row=7)
users = dict()
realusers = []
pwds = []
window.mainloop()
It is because of this line:
btn2 = Button(window, text="Create Account", command=create_account())
command=create_account will run create_account once the line is executed. All you need to do is remove the parenthesis and most likely it will work just fine.
My program creates a simple application, using Tkinter, that aims to compare a user's details (username and password) to a file.
My program uses 3 frames.
-"usernameFrame"
-"passwordFrame"
-"resultFrame"
It has a username label calld "ulab" and a password label called "plab"
It has an "Output" label which tells the user if he has successfully logged in or not
At the bottom it has a Login button which connects to the command "LoginF".
However, I always get the error "TypeError: LoginF() missing 2 required positional arguments: 'username' and 'password"
from tkinter import *
root = Tk()
root.title("Validating user details")
Title = Label(root,text="Welcome, please login below", fg = "blue", bg = "yellow", font = "Verdana 30 bold", bd=1, relief="solid",padx=20)
Title.pack(side = TOP)
usernameFrame = Frame(root)
usernameFrame.pack(side = TOP)
uLab = Label(usernameFrame,text="Enter username: ",fg="light green",bg="green",font = "Calibri 26 italic",bd=1, relief="solid")
uLab.pack(side = LEFT)
username = Entry(usernameFrame)
username.pack(side = LEFT)
passwordFrame = Frame(root)
passwordFrame.pack(side = TOP)
pnLab = Label(passwordFrame,text="Enter password: ",fg="light green",bg="green",font = "Calibri 26 italic",bd=1, relief="solid")
pnLab.pack(side = LEFT,fill = X,expand = 1)
password = Entry(passwordFrame,show="*")
password.pack(side = LEFT)
resultFrame = Frame(root)
resultFrame.pack(side = TOP)
Output = Label(resultFrame,text="Display Result Here",fg="#008080",bg="#00FFFF",font = "Tahoma 30 bold",bd=1, relief="solid")
Output.pack(side = LEFT,fill = X,expand = 1)
def LoginF(username,password):
Login = False
file = open("OCR PPP Python Login List_user.txt","r")
data = file.read()
if username+","+password in data:
Output.configure(text="Successfully logged in")
Login = True
else:
Output.configure(text="Hmm.. Try again")
Login = False
file.close()
logButton = Button(resultFrame,text="Login",fg="#FF8C00",bg="#FF4500",font = "Ariel 28 underline",bd=1, relief="solid",command=LoginF)
logButton.pack(side = LEFT)
root.mainloop()
This is because you haven't pass any arguments to the LoginF(...) function.
Either you do this:
logButton = Button(resultFrame,text="Login",fg="#FF8C00",bg="#FF4500",font = "Ariel 28 underline",bd=1, relief="solid",
command=lambda: LoginF(username.get(), password.get()))
To know more about how to pass functions as callback in tkinter.
Or
Change your LoginF() a little bit like so.
def LoginF():
username = username.get()
password = password.get()
Login = False
file = open("OCR PPP Python Login List_user.txt","r")
data = file.read()
if username+","+password in data:
Output.configure(text="Successfully logged in")
Login = True
else:
Output.configure(text="Hmm.. Try again")
Login = False
file.close()