Why my code is not working? - python

New to tkinter, but as of now, I don't know why my code keeps returning Failed instead of passed.
import tkinter as tk
class GUI(tk.Tk):
def __init__(self):
tk.Tk.__init__(self)
self.entry = tk.Entry(self)
self.user_Label = tk.Label(self, text="Username")
self.pass_entry = tk.Entry(self)
self.pass_Label = tk.Label(self, text="Password")
self.login = tk.Button(self, text="Login", foreground="black", command=self.on_button)
#Packing
self.user_Label.pack()
self.entry.pack()
self.pass_Label.pack()
self.pass_entry.pack()
self.login.pack()
def on_button(self):
if self.entry and self.pass_entry == "hello":
print("passed")
else:
print("Failed")
app = GUI()
app.mainloop()

It does not work because you need to use the following to get the value of the password entered:
self.pass_entry.get()
Consequently, you should have:
if self.entry.get() and self.pass_entry.get() == "hello":
As a side note. If you have password Entry widget, better to do it as follows:
self.pass_entry = tk.Entry(self, show="*")

Related

How to pass data between top levels in tkinter

I am totally new to tkinter. I am trying to pass data between two windows. There is a button on root window. button press will open a top level. There are two entry fields and a submit button in on toplevel window. user can enter two number and submit. What i am trying to achieve is, pressing submit button should close the top level and result (sum) should be shown in the root window. How to pass entry field data to root window?
from tkinter import *
root= Tk()
root.geometry('600x400')
sum_var= StringVar()
def entry_Fn():
level_1 = Toplevel(root)
Label( level_1, text = "level one").pack()
entry_1 =Entry(level_1)
entry_1.pack()
entry_2 =Entry(level_1)
entry_2.pack()
Button(level_1, text= "submit", command= submitBtn ).pack()
def submitBtn():
val_1= entry_1.get()
val_2= entry_2.get()
sum_var.set(int(val_1)+ int(val_2))
Label(root, text = "Main window").pack()
Button(root, text= "To enter Data", command= entry_Fn).pack()
sum = Label(root, textvariable = sum_var)
sum.pack()
root.mainloop()
#result
val_1= entry_1.get()
NameError: name 'entry_1' is not defined
#shall I define some global variables?
In this case, you don't have to declare global. Simply indent your submitBtn function inside entry_Fn:
def entry_Fn():
level_1 = Toplevel(root)
Label( level_1, text = "level one").pack()
entry_1 = Entry(level_1)
entry_1.pack()
entry_2 = Entry(level_1)
entry_2.pack()
def submitBtn():
val_1= entry_1.get()
val_2= entry_2.get()
sum_var.set(int(val_1)+ int(val_2))
level_1.destroy()
Button(level_1, text= "submit", command=submitBtn).pack()
But generally it is easier to make a class so you can avoid this kind of scope problems, like below:
from tkinter import *
class GUI(Tk):
def __init__(self):
super().__init__()
self.geometry('600x400')
self.sum_var= StringVar()
Label(self, text="Main window").pack()
Button(self, text="To enter Data", command=self.entry_Fn).pack()
sum = Label(self, textvariable=self.sum_var)
sum.pack()
def entry_Fn(self):
self.level_1 = Toplevel(self)
Label(self.level_1, text = "level one").pack()
self.entry_1 = Entry(self.level_1)
self.entry_1.pack()
self.entry_2 = Entry(self.level_1)
self.entry_2.pack()
Button(self.level_1, text="submit", command=self.submitBtn).pack()
def submitBtn(self):
val_1 = self.entry_1.get()
val_2 = self.entry_2.get()
self.sum_var.set(int(val_1)+ int(val_2))
self.level_1.destroy()
root = GUI()
root.mainloop()
For your case, you can simply pass the two entries to submitBtn() function:
def submitBtn(entry_1, entry_2):
....
Then update the command= for the submit button inside entry_Fn():
Button(level_1, text="submit", command=lambda: submitBtn(entry_1, enter_2)).pack()
You can subclass tk.TopLevel, and use a tk.IntVar to transfer the data back to root:
import tkinter as tk
class EntryForm(tk.Toplevel):
def __init__(self, master, sum_var):
super().__init__(master)
tk.Label(self, text="level one").pack()
self.sum_var = sum_var
self.entry_1 = tk.Entry(self)
self.entry_1.pack()
self.entry_2 = tk.Entry(self)
self.entry_2.pack()
tk.Button(self, text="submit", command=self.submitBtn).pack()
def submitBtn(self):
val_1 = self.entry_1.get()
val_2 = self.entry_2.get()
self.sum_var.set(int(val_1) + int(val_2))
self.destroy()
def spawn_entry_popup():
EntryForm(root, sum_var)
root= tk.Tk()
root.geometry('600x400')
sum_var = tk.IntVar()
tk.Label(root, text = "Main window").pack()
tk.Button(root, text= "To enter Data", command=spawn_entry_popup).pack()
sum_label = tk.Label(root, textvariable=sum_var)
sum_label.pack()
root.mainloop()
You can also place your app inside a class:
import tkinter as tk
class EntryForm(tk.Toplevel):
def __init__(self, master, sum_var):
super().__init__(master)
tk.Label(self, text="level one").pack()
self.sum_var = sum_var
self.entry_1 = tk.Entry(self)
self.entry_1.pack()
self.entry_2 = tk.Entry(self)
self.entry_2.pack()
tk.Button(self, text="submit", command=self.submitBtn).pack()
def submitBtn(self):
val_1 = self.entry_1.get()
val_2 = self.entry_2.get()
self.sum_var.set(int(val_1) + int(val_2))
class GUI(tk.Tk):
def __init__(self):
super().__init__()
self.geometry('600x400')
self.sum_var = tk.IntVar()
tk.Label(self, text = "Main window").pack()
tk.Button(self, text= "To enter Data", command=self.spawn_entry_popup).pack()
sum_label = tk.Label(self, textvariable=self.sum_var)
sum_label.pack()
def spawn_entry_popup(self):
EntryForm(self, self.sum_var)
GUI().mainloop()

If i have a login window and want to access another window after i logged in, do i need to use another def into it

a beginner here, I was hoping to open a new window after I logged the correct entry by trying to put import filename.py but it won't show after the tm.showinfo. I don't know what function that will make it happen at the same time it will closed or quit my login window.
I've tried my previous way of doing it to call a command and making a function for it but now I'm totally confused about it,
from tkinter import *
import tkinter.messagebox as tm
class adminlog(Frame):
def __init__(self, master):
super().__init__(master)
self.label_username = Label(self, text="Username")
self.label_password = Label(self, text="Password")
self.entry_username = Entry(self)
self.entry_password = Entry(self, show="*")
self.label_username.grid(row=0, sticky=E)
self.label_password.grid(row=1, sticky=E)
self.entry_username.grid(row=0, column=1)
self.entry_password.grid(row=1, column=1)
self.logbtn = Button(self, text="Login as Admin", command=self.lg_admin)
self.logbtn.grid(columnspan=2)
self.pack()
def lg_admin(self):
un = self.entry_username.get()
ps = self.entry_password.get()
if un == "admin" and ps == "pito":
tm.showinfo("Login Info", "Login Successfully")
import adminpage
else:
tm.showerror("Login Error", "Incorrect password or username")
admin = Tk()
a = adminlog(admin)
admin.mainloop()
I expect that after I am logged in, then a new window will open after the tm.showinfo shows.
It really depends upon your choice and feel. I will give you two methods and let you decide.
Disclaimer : I prefer the first method.
It is not a good practice to create two Tk() windows in the same program. What you can do is have one main window and configure it as and when you want. Here for example, the function clear_widgets() clears the login page and shows the next page.
import tkinter as tk
import tkinter.messagebox as tm
class adminlog(tk.Tk):
def __init__(self):
super().__init__()
tk.Label(self, text="Username").grid(row=0, sticky="e")
tk.Label(self, text="Password").grid(row=1, sticky="e")
self.entry_username = tk.Entry(self)
self.entry_password = tk.Entry(self, show="*")
self.entry_username.grid(row=0, column=1)
self.entry_password.grid(row=1, column=1)
logbtn = tk.Button(self, text="Login as Admin", command=self.lg_admin)
logbtn.grid(columnspan=2)
def adminpage(self):
self.clear_widgets()
tk.Label(self, text='Hello Admin !!', bg='brown', fg='white').grid(row=0, column=1, padx=20, pady=20)
def clear_widgets(self):
for widget in self.winfo_children():
widget.destroy()
def lg_admin(self):
un = self.entry_username.get()
ps = self.entry_password.get()
if un == "admin" and ps == "pito":
tm.showinfo("Login Info", "Login Successfully")
self.adminpage()
else:
tm.showerror("Login Error", "Incorrect password or username")
adminlog().mainloop()
If you really want another window and can't do without it, you should use a Toplevel. Here is a demonstration.
import tkinter as tk
import tkinter.messagebox as tm
class adminlog(tk.Tk):
def __init__(self):
super().__init__()
tk.Label(self, text="Username").grid(row=0, sticky="e")
tk.Label(self, text="Password").grid(row=1, sticky="e")
self.entry_username = tk.Entry(self)
self.entry_password = tk.Entry(self, show="*")
self.entry_username.grid(row=0, column=1)
self.entry_password.grid(row=1, column=1)
logbtn = tk.Button(self, text="Login as Admin", command=self.lg_admin)
logbtn.grid(columnspan=2)
def adminpage(self):
adp = tk.Toplevel(self)
tk.Label(adp, text='Hello Admin !!', bg='brown', fg='white').grid(row=0, column=1, padx=20, pady=20)
def lg_admin(self):
un = self.entry_username.get()
ps = self.entry_password.get()
if un == "admin" and ps == "pito":
tm.showinfo("Login Info", "Login Successfully")
self.adminpage()
else:
tm.showerror("Login Error", "Incorrect password or username")
adminlog().mainloop()
Here you can see, the login window won't go away (if it does, it will take the Toplevel with it also). So, I would recommend you to use the first method.

How to disable a button by a checkbox in Tkinter

I'm studying GUI for Python, and I don't know how to disable a button with a check button. Which trigger does Python use to verify if I mark the check button? Follow some code I wrote trying to do it, but without success.
Sorry for my bad English.
from tkinter import *
from tkinter import ttk
class HelloApp:
def __init__(self, master):
self.label = ttk.Label(master, text="Hello, Tkinter!")
self.button1 = ttk.Button(master, text="Texas", command=self.texas_hello)
self.button2 = ttk.Button(master, text="Hawaii", command=self.hawaii_hello)
value_check = IntVar()
def disable_button(button):
button.config(state=DISABLED)
def enable_button(button):
button.config(state=NORMAL)
checkbutton = ttk.Checkbutton(master, variable=value_check, text='Deactivate!',
onvalue=enable_button(self.button1),
offvalue=disable_button(self.button1))
self.label.grid(row=0, column=0, columnspan=2)
self.button1.grid(row=1, column=0)
self.button2.grid(row=1, column=1)
checkbutton.grid(row=1, column=2)
print(value_check)
def texas_hello(self):
self.label.config(text='Howdy, Tkinter!')
def hawaii_hello(self):
self.label.config(text='Aloha, Tkinter!')
def main():
root = Tk()
HelloApp(root)
root.mainloop()
if __name__ == "main": main()
main()
You have to pass a function to command, this function is the one that will be notified every time there is a change, and you can get the status through value_check.
...
value_check = IntVar()
def disable_enable_button(button):
self.button1.config(state=DISABLED if value_check.get() else NORMAL)
checkbutton = ttk.Checkbutton(master, variable=value_check, text='Deactivate!',
command=disable_enable_button)
....
use command option. you can set the default status using value_check.set(1/0).
def disable_button(self, button):
print('disable button')
button.config(state=DISABLED)
def enable_button(self, button):
print('enable button')
button.config(state=NORMAL)
def changebutton(self):
print('changebutton=', self.value_check.get())
if self.value_check.get()==1:
self.enable_button(self.button1)
else:
self.disable_button(self.button1)
def __init__(self, master):
self.label = ttk.Label(master, text="Hello, Tkinter!")
self.button1 = ttk.Button(master, text="Texas", command=self.texas_hello)
self.button2 = ttk.Button(master, text="Hawaii", command=self.hawaii_hello)
self.value_check = IntVar()
self.checkbutton = ttk.Checkbutton(master, variable=self.value_check, text='Activate!',
onvalue=1, offvalue=0,
command=self.changebutton)
self.value_check.set(0)
self.changebutton()
self.label.grid(row=0, column=0, columnspan=2)
self.button1.grid(row=1, column=0)
self.button2.grid(row=1, column=1)
self.checkbutton.grid(row=1, column=2)
print(self.value_check.get())
Follows the code including some radio buttons to play with the checkbox.
class HelloApp:
def __init__(self, master):
self.label = ttk.Label(master, text="Hello, Tkinter!")
self.button1 = ttk.Button(master, text="Texas", command=self.texas_hello)
self.button2 = ttk.Button(master, text="Hawaii", command=self.hawaii_hello)
self.value_check = IntVar()
self.value_check.set(0)
self.checkbutton = ttk.Checkbutton(master, variable=self.value_check, text='Activate!',
onvalue=1, offvalue=0,
command=self.disable_enable_button)
self.choice = StringVar()
self.frame_radio = ttk.Frame(master).grid(row=3, column=3)
self.radiobutton1 = ttk.Radiobutton(self.frame_radio, text='Button 1', variable=self.choice, value='button1')
self.radiobutton1.grid(row=2, column=2)
self.radiobutton2 = ttk.Radiobutton(self.frame_radio, text='Button 2', variable=self.choice, value='button2')
self.radiobutton2.grid(row=3, column=2)
self.label.grid(row=0, column=0, columnspan=2)
self.button1.grid(row=1, column=0)
self.button2.grid(row=1, column=1)
self.checkbutton.grid(row=1, column=2)
def texas_hello(self):
self.label.config(text='Howdy, Tkinter!')
def hawaii_hello(self):
self.label.config(text='Aloha, Tkinter!')
def disable_enable_button(self):
self.button1.config(
state=DISABLED if self.value_check.get() and self.choice.get() == 'button1' else NORMAL)
self.button2.config(
state=DISABLED if self.value_check.get() and self.choice.get() == 'button2' else NORMAL)
def main():
root = Tk()
HelloApp(root)
root.mainloop()

My gui app is not working coorectly

The code is for a gui app that has a login page
from tkinter import *
import tkinter.messagebox as tm
import restaurant_management_system
class LoginFrame(Frame):
def __init__(self, master):
super().__init__(master)
self.label_1 = Label(self, text="Username")
self.label_2 = Label(self, text="Password")
self.entry_1 = Entry(self)
self.entry_2 = Entry(self, show="*")
self.label_1.grid(row=0, sticky=E)
self.label_2.grid(row=1, sticky=E)
self.entry_1.grid(row=0, column=1)
self.entry_2.grid(row=1, column=1)
self.checkbox = Checkbutton(self, text="Keep me logged in")
self.checkbox.grid(columnspan=2)
self.logbtn = Button(self, text="Login", command = self._login_btn_clickked)
self.logbtn.grid(columnspan=2)
self.pack()
def _login_btn_clickked(self):
#print("Clicked")
username = self.entry_1.get()
password = self.entry_2.get()
#print(username, password)
if username == "john" and password == "password":
tm.showinfo("Login info", "Welcome John")
else:
tm.showerror("Login error", "Incorrect username")
root = Tk()
lf = LoginFrame(root)
root.mainloop()
I have imported another py file however i don't know how to run it when the user login successfully.
You basically need to check if the username and password are correct and then destroy the frame that the widgets are contained in and redraw whatever you want on the other side:
from tkinter import *
class App:
def __init__(self, root):
self.username = "Username"
self.password = "Password"
self.root = root
self.frame = Frame(self.root)
self.entry1 = Entry(self.frame)
self.entry2 = Entry(self.frame)
self.button1 = Button(self.frame, text="Ok", command=self.login)
self.frame.pack()
self.entry1.pack()
self.entry2.pack()
self.button1.pack()
def login(self):
if self.entry1.get() == self.username and self.entry2.get() == self.password:
self.frame.destroy()
self.frame = Frame(self.root)
self.label = Label(self.frame, text="You are logged in")
self.frame.pack()
self.label.pack()
root = Tk()
App(root)
root.mainloop()

Tkinter - show dialog with options and change password buttons

I use a python program called Thonny. Its used to make another box that said 'You have made it into the main application' inside but I removed that piece of text for now. I would like it to show a options button and a change password button. This is the code:
import tkinter as tk
class Mainframe(tk.Tk):
def __init__(self):
tk.Tk.__init__(self)
self.frame = FirstFrame(self)
self.frame.pack()
def change(self, frame):
self.frame.pack_forget() # delete currrent
frame = frame(self)
self.frame.pack() # make new frame
class FirstFrame(tk.Frame):
def __init__(self, master=None, **kwargs):
tk.Frame.__init__(self, master, **kwargs)
master.title("Enter password")
master.geometry("300x200")
self.status = tk.Label(self, fg='red')
self.status.pack()
lbl = tk.Label(self, text='Enter password')
lbl.pack()
self.pwd = tk.Entry(self, show="*")
self.pwd.pack()
self.pwd.focus()
self.pwd.bind('<Return>', self.check)
btn = tk.Button(self, text="Done", command=self.check)
btn.pack()
btn = tk.Button(self, text="Cancel", command=self.quit)
btn.pack()
def check(self, event=None):
if self.pwd.get() == 'password':
self.master.change(SecondFrame)
else:
self.status.config(text="Wrong password")
class SecondFrame(tk.Frame):
def __init__(self, master=None, **kwargs):
tk.Frame.__init__(self, master, **kwargs)
master.title("Main application")
master.geometry("600x400")
def options_button(self):
def set_password(self):
e = tk.Entry(master, show="*", textvariable=self.password_set2)
e.pack()
but1 = tk.Button(self, text="Done", command=self.password_set)
but1.pack()
b = tk.Button(self, text="Set your password", command=self.set_password)
b.pack()
c = tk.Button(self, text="Options", command=self.options_button)
c.pack()
if __name__=="__main__":
app=Mainframe()
app.mainloop()
This is What is not working.
This is what it originally did
So I had a little bit of a play around and I think this is what your after. I also changed your code a little bit as I always feel its best to put self infront of all widgets on multiclass applications.
import tkinter as tk
class FirstFrame(tk.Frame):
def __init__(self, master, **kwargs):
tk.Frame.__init__(self, master, **kwargs)
self.pack()
master.title("Enter password")
master.geometry("300x200")
self.status = tk.Label(self, fg='red')
self.status.pack()
self.lbl = tk.Label(self, text='Enter password')
self.lbl.pack()
self.pwd = tk.Entry(self, show="*")
self.pwd.pack()
self.pwd.focus()
self.pwd.bind('<Return>', self.check)
self.btn = tk.Button(self, text="Done", command=self.check)
self.btn.pack()
self.btn = tk.Button(self, text="Cancel", command=self.quit)
self.btn.pack()
def check(self, event=None):
if self.pwd.get() == app.password:
self.destroy() #destroy current window and open next
self.app= SecondFrame(self.master)
else:
self.status.config(text="Wrong password")
class SecondFrame(tk.Frame):
#re organised a lot in here
def __init__(self, master, **kwargs):
tk.Frame.__init__(self, master, **kwargs)
self.pack()
master.title("Main application")
master.geometry("600x400")
self.c = tk.Button(self, text="Options", command=self.options_button)
self.c.pack()
self.e = tk.Entry(self.master, show="*")
def options_button(self):
self.e.pack()
self.but1 = tk.Button(self, text="Change password", command=self.set_password)
self.but1.pack()
def set_password(self):
app.password=self.e.get()
if __name__=="__main__":
root = tk.Tk() #removed your mainframe class
app=FirstFrame(root)
#set an attribute of the application for the password
#similar to a global variable
app.password = "password"
root.mainloop()
So with what I have done you get prompted for the password and if you get it right it goes to the next scree, then an options button appears and if it is clicked then an entry box appears allowing the user to change the password

Categories

Resources