How to allow a tkinter window to be opened multiple times - python

I am making a makeshift sign in system with python. Currently if you enter the correct password it brings up a new admin window. If you enter the wrong one it brings up a new window that says wrong password. If you exit out of one of those windows and then try to enter a password again it breaks. tkinter.TclError: can't invoke "wm" command: application has been destroyed Is there a way to prevent this so if someone enters the wrong password they don't need to restart the app?
import tkinter
from tkinter import *
#define root window
root = tkinter.Tk()
root.minsize(width=800, height = 600)
root.maxsize(width=800, height = 600)
#define admin window
admin = tkinter.Tk()
admin.minsize(width=800, height = 600)
admin.maxsize(width=800, height = 600)
admin.withdraw()
#define wrong window
wrong = tkinter.Tk()
wrong.minsize(width=200, height = 100)
wrong.maxsize(width=200, height = 100)
wrong.withdraw()
Label(wrong, text="Sorry that password is incorrect!", font=("Arial", 24), anchor=W, wraplength=180, fg="red").pack()
#Admin sign in Label
areAdmin = Label(root, text="Administrator sign in", font=("Arial", 18))
areAdmin.pack()
#password label and password
passwordLabel = Label(root, text="Password: ", font=("Arial", 12))
passwordLabel.place(x=300, y=30)
#password entry
adminPasswordEntry = Entry(root)
adminPasswordEntry.place(x=385, y=32.5)
#function for button
def getEnteredPassword():
enteredPassword = adminPasswordEntry.get()
if enteredPassword == password:
admin.deiconify()
else:
wrong.deiconify()
#enter button for password
passwordEnterButton = Button(root, text="Enter", width=20, command=getEnteredPassword)
passwordEnterButton.place(x=335, y=60)
mainloop()

I don't know tkinter much but I could fix your code, I hope it's a proper fix.
Create Toplevel windows not Tk. those are dialog windows, as opposed to Tk window which must be unique. Same look & feel, same methods
Create windows when needed, and each time. Else, closing them using the close gadget destroys them.
Fixed code, enter wrong or good password as many times you want without crash:
import tkinter
from tkinter import *
password="good"
#define root window
root = tkinter.Tk()
root.minsize(width=800, height = 600)
root.maxsize(width=800, height = 600)
#Admin sign in Label
areAdmin = Label(root, text="Administrator sign in", font=("Arial", 18))
areAdmin.pack()
#password label and password
passwordLabel = Label(root, text="Password: ", font=("Arial", 12))
passwordLabel.place(x=300, y=30)
#password entry
adminPasswordEntry = Entry(root)
adminPasswordEntry.place(x=385, y=32.5)
#function for button
def getEnteredPassword():
enteredPassword = adminPasswordEntry.get()
if enteredPassword == password:
admin = tkinter.Toplevel()
admin.minsize(width=800, height = 600)
admin.maxsize(width=800, height = 600)
#admin.withdraw()
else:
wrong = tkinter.Toplevel()
wrong.minsize(width=200, height = 100)
wrong.maxsize(width=200, height = 100)
Label(wrong, text="Sorry that password is incorrect!", font=("Arial", 24), anchor=W, wraplength=180, fg="red").pack()
#enter button for password
passwordEnterButton = Button(root, text="Enter", width=20, command=getEnteredPassword)
passwordEnterButton.place(x=335, y=60)
mainloop()

Related

Python Tkinter: Is there a way to have text and buttons with the button placed on the x and y axes?

I'm trying to get text and a button where the button is placed using place(). See the code:
import tkinter as t
w = t.Tk()
w.title("TaxNow Beta")
w.geometry('2000x6000')
c = t.Canvas(w, width="6000", height="2000", bg="White")
frame = t.Frame(w)
frame.pack(fill="both", expand=True)
c.create_text(900,50,text="Please Login", font=("Montserrat 32"))
frame.pack()
loginButton = t.Button(frame, text="Log In")
loginButton.place(x=100, y=150)
w.mainloop()
The text isn't showing up.
Can someone help?
is this what you're trying to do ?
import tkinter as tk
w = tk.Tk()
w.title("TaxNow Beta")
w.geometry("400x600")
frame = tk.Frame(w)
login_button = tk.Button(frame, text="Log In", font=("Montserrat 15"))
login_text = tk.Label(frame, text="Please Log In", font=("Montserrat 20"))
login_button.pack(ipadx=25)
login_text.pack(pady=10)
frame.pack(expand=True)
w.mainloop()

(python) Disable the button in Tkinter when passwords do not match

How to disable the button in tkinter window when two passwords does not match?
My work:
from tkinter import *
from functools import partial
root = Tk()
root.geometry('280x100')
root.title('Tkinter Password')
def validation_pw(ep,cp):
if ep.get() == cp.get():
Label(root, text = "Confirmed").grid(column=0, row=5)
else:
Label(root, text = "Not matched").grid(column=0, row=5)
# check_button['state'] = DISABLED <============================
ep = StringVar()
cp = StringVar()
Label1 = Label(root, text = "Enter Password").grid(column=0, row=0)
pwEnty = Entry(root, textvariable = ep, show = '*').grid(column=1, row=0)
# Confirmed password label
Label2 = Label(root, text = "Confirm Password").grid(column=0, row=1)
pwconfEnty = Entry(root, textvariable = cp, show = '*').grid(column=1, row=1)
validation_pw = partial(validation_pw, ep,cp)
check_button = Button(root, text = "check", command = validation_pw).grid(column=0, row=4)
root.mainloop()
It shows if two passwords are not matched.
Now, I want to disable the check button if two passwords are not matched. I want the user cannot try the passwords anymore if failure.
So in the function validation_pw, I add check_button['state'] = DISABLED.
However, an error pops out
TypeError: 'NoneType' object does not support item assignment
How to fix this issue? Thanks!
Your checkbutton is actually None, because it's the result of the grid function.
To fix it, first declare the button, next grid it.
Before:
check_button = Button([...]).grid(column=0, row=4) # Result of Button.grid function
print(check_button) # None
After:
check_button = Button([...])
check_button.grid(column=0, row=4)
print(check_button) # Button object ...
You get the error of NoneType because at one point it was assigned nothing. This is because you used .grid on the same line as the button.
Fixed code:
check_button = Button(root, text = "check", command = validation_pw)
check_button.grid(column=0, row=4)

TypeError: mainloop() missing 1 required positional argument: 'self'

I am trying to code a little login/sign-in GUI in tkinter. When the program starts, the Login window pops up. When I press the "Sign in" button, I get this: TypeError: mainloop() missing 1 required positional argument: 'self'
Here's the code I'm working with:
#importing
import tkinter as tk
#creating all of the widgets for the login
root = tk.Tk()
root.geometry("200x120")
loglab = tk.Label(text="Login")
userlab = tk.Label(text="Username")
passlab = tk.Label(text="Password")
username = tk.Entry(root)
password = tk.Entry(root,show="*")
#defining the button functions
def signin():
root.destroy
signroot = tk.Toplevel
userlab = tk.Label(text="Username")
passlab = tk.Label(text="Password")
username = tk.Entry(root)
password = tk.Entry(root,show="*")
signroot.mainloop()
#creating the login root buttons
signb = tk.Button(text="Sign In",command=signin)
#gridding the widgets
loglab.grid(row=0,column=0,pady=10)
userlab.grid(row=1,column=0)
username.grid(row=1,column=1,padx = 5)
passlab.grid(row=2,column=0)
password.grid(row=2,column=1,padx = 5)
signb.grid(row=3,column=0,pady=5)
root.mainloop()
Try this:
#importing
import tkinter as tk
wrong_password_label = None
#defining the button functions
def signin():
global wrong_password_label
# Check if the password the user entered is: "my password"
if password.get() == "my password":
root.destroy()
signroot = tk.Tk()
userlab = tk.Label(signroot, text="You are logged in!")
userlab.grid(row=1, column=1)
signroot.mainloop()
else:
# If the password is wrong:
if wrong_password_label is None:
# If there isn't a `wrong_password_label` widget defined:
wrong_password_label = tk.Label(root, text="Wrong Password", fg="red")
wrong_password_label.grid(row=4, column=0, columnspan=2)
else:
# If there is a `wrong_password_label` widget defined:
wrong_password_label.config(text="Still wrong")
#creating all of the widgets for the login
root = tk.Tk()
# root.geometry("200x120") # You don't need this when using `.grid` or `.pack`
loglab = tk.Label(root, text="Login")
userlab = tk.Label(root, text="Username")
passlab = tk.Label(root, text="Password")
username = tk.Entry(root)
password = tk.Entry(root, show="*")
#creating the login root buttons
signb = tk.Button(root, text="Sign In", command=signin)
#gridding the widgets
loglab.grid(row=0, column=0, pady=10)
userlab.grid(row=1, column=0)
username.grid(row=1, column=1, padx = 5)
passlab.grid(row=2, column=0)
password.grid(row=2, column=1, padx = 5)
signb.grid(row=3, column=0, pady=5)
root.mainloop()
I think that is what you were trying to do. It checks if the password is my password and if it is, it destroys the old window and creates a new one. If the password is wrong, it tells the user. You can also add a check for the username.

Text is not showing in Tkinter

the Label (showpw) (inside: def passwort_gen) I placed on the grid is not visible in the application window. When I run the code and press the button, the original button moves up to make place for the text, like it should, the text however is not visible.
Below you can see the entire project code. It's my first project using Tkinter so I apologize for the messy structure.
import tkinter as tk
import random
import pyperclip as pc
root = tk.Tk()
canvas = tk.Canvas(root, width=600, height=300)
canvas.grid(columnspan=3, rowspan=3)
#Header
Header = tk.StringVar()
text = tk.Label(root, textvar=Header, font="helvetica")
Header.set("Passwort Generator")
chars = "abcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ!§$%&/()=?*#'#"
passwords = []
text.grid(columnspan=3, column=0, row=0)
def neues_passwort():
gen = tk.StringVar()
gen_btn = tk.Button(root, textvar=gen, command=lambda:passwort_gen(), font="helvetica")
gen.set("Passwort Generieren")
gen_btn.grid(column=1, row=1)
Header.set("Neues Passwort")
def passwort_gen():
for p in range(1):
password = ""
for c in range(12):
password += random.choice(chars)
pwtext = tk.StringVar()
showpw = tk.Label(root, textvar=pwtext, font="helvetica", fg="#000000")
pwtext.set = "Dein Passwort ist:", password, ". Es wurde zum Clipboard hinzugefügt"
showpw.grid(columnspan=3, column=1, row=2,)
pc.copy(password)
#button
text = tk.StringVar()
browse_btn = tk.Button(root, textvar=text, command=lambda:neues_passwort(), font="helvetica")
text.set("neues Passwort")
browse_btn.grid(column=1, row=1)
root.mainloop()
pwtext.set is a function, not a string container. Use pwtext.set("Dein Passwort ist:" + password + ". Es wurde zum Clipboard hinzugefügt") instead.

How can I display output from a button command in a new window using tkinter?

I have successfully created a GUI that takes user input and gives the desired output, but I can't seem to figure out how to display this output in another window instead of just in the IDE console. My goal is to have a window pop up with the output once the user clicks 'Compute BMI', but as of right now, the output only shows in the console. I have looked for solutions but I can't seem to figure out what tools I can use to make this happen. I am new to GUIs so any help would be much appreciated.
from tkinter import *
root = Tk()
def myBMI():
weight = float(Entry.get(weight_field))
height = float(Entry.get(height_field))
bmi = (weight*703)/(height*height)
print(bmi)
height_label = Label(root, text="Enter your height: ")
height_field = Entry(root)
height_field.grid(row=0, column=1)
height_label.grid(row=0, sticky=E)
weight_label = Label(root, text="Enter your weight: ")
weight_field = Entry(root)
weight_field.grid(row=1, column=1)
weight_label.grid(row=1, sticky=E)
compute_bmi = Button(root, text="Compute BMI", command=myBMI)
compute_bmi.grid(row=2)
root.mainloop()
tkinter "pop-ups" should typically be handled via the tk.TopLevel() method! This will generate a new window that can be titled or have buttons put in it like:
top = Toplevel()
top.title("About this application...")
msg = Message(top, text=about_message)
msg.pack()
button = Button(top, text="Dismiss", command=top.destroy)
button.pack()
So instead of print(bmi) you could do something like, say:
top = tk.Toplevel()
msg = tk.Label(top, text=bmi)
msg.pack()
More documentation can be found at http://effbot.org/tkinterbook/toplevel.htm!

Categories

Resources