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()
Related
I am creating a gui using tkinter, i need to work with a login window and subsequent windows, i am unable to place any label on new windows as it says 'testclass' object has no attribute 'tk'
My main objective is to create a new window after logging in and hiding the login window and then work with the new window and place label and create a form
from tkinter import *
import tkinter.messagebox as tm
class LoginFrame(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", command=self._login_btn_clicked)
self.logbtn.grid(columnspan=2)
self.pack()
# def verifycred(self,username,password):
def _login_btn_clicked(self):
username = self.entry_username.get()
password = self.entry_password.get()
# verify_out = self.verifycred(username,password)
self.newWindow = Toplevel(self.master)
self.app = randomclass(self.newWindow)
class randomclass(LoginFrame):
def __init__(self,master):
self.master = master
self.master.title("Random Class")
self.master.geometry("1350x750+250+150")
self.master.config(bg ='cadet blue')
self.frame = Frame(self.master, bg = 'powder blue')
self.frame.pack()
self.test = Button(self.frame,text='Random',width = 25, command = self.random)
self.test.grid(row=4,column=0)
def random(self):
self.newWindow = Toplevel(self.master)
self.app = testclass(self.newWindow)
class testclass(LoginFrame):
def __init__(self,master):
self.master = master
self.master.title("Test")
self.master.geometry("1350x750+250+150")
self.master.config(bg ='cadet blue')
self.frame = Frame(self.master, bg = 'powder blue')
self.frame.pack()
self.welcome = Label(self,text='Hello')
self.welcome.grid(row=0,column=1)
root = Tk()
lf = LoginFrame(root)
root.mainloop()
There's Only small problem that you are forgot to write self.master inside a label widget declaration of testclass.
Here's The Solution,
class testclass(LoginFrame):
def __init__(self,master):
self.master = master
self.master.title("Test")
self.master.geometry("1350x750+250+150")
self.master.config(bg ='cadet blue')
self.frame = Frame(self.master, bg = 'powder blue')
self.frame.grid(row = 0,column = 0)
self.welcome = Label(self.master,text='Hello')
self.welcome.grid(row=0,column=1)
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()
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.
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
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="*")