Tkinter open a new window from an already open window - python

I have trouble with Tkinter to open a new window(from another module).
In Log.py module we have the code to catch the Name
and Id from the User.
Entered data is sent to db.py and checked.
If the User Name and Id exist in the DB db.py, it will return True
to Log.py module and with the result from the callback function will open the test_win.py.
My trouble is in 3. (1. and 2. have been tested and without 3. and they work well).
When I added the function that if the result from the callback function is True, it does not work as expected.
When I run the script with def open_inventory it opens first the test_win.py and once done, it closes test_win.py and opens Log.py when it should be the oposite.
Appreciate any suggestions/answers to fix the above issue.
Log.py
import tkinter as tk
from tkinter import ttk, messagebox
from _userDB import *
import test_win
db = UserDb()
class Login:
def __init__(self, window):
self.window = window
self.window.geometry("300x300")
self.window.title("Inventory")
self.window.eval("tk::PlaceWindow . center")
title1 = ttk.Label(window, text=f"Inventory\n", font=('helvetica', 18, 'bold'))
title1.pack()
subtitle1 = ttk.Label(window, text=f"Log in\n", font=('helvetica', 16, 'bold'))
subtitle1.pack()
login_name = ttk.Label(window, text=f"Name: ", font=('helvetica', 12, 'bold'))
login_name.pack(anchor='center')
self.log_name_entry = ttk.Entry()
self.log_name_entry.pack()
login_id = ttk.Label(window, text=f"ID:", font=('helvetica', 12, 'bold'))
login_id.pack()
self.log_id_entry = ttk.Entry()
self.log_id_entry.pack()
enter_btn = tk.Button(window, text=f"Log in", font=('Helvetica', 14, 'bold'), bg='#A9A9A9', cursor="hand2",
activebackground="#696969",
command=lambda: self.check())
enter_btn.pack(pady=15)
# here send data to the db.py module to check in the DB if the User name and id exist
def check(self):
user_name = self.log_name_entry.get()
user_id = self.log_id_entry.get()
print(user_name, user_id)
if user_name == "" and user_id == "" or user_name == "" or user_id == "":
messagebox.showwarning("ERROR", 'All tha cases most be filling')
else:
db.user_check(user_name, user_id, self.open_inventory())
# If result from db.py is True open the new window(test_win.py)
def open_inventory(self, result):
if result:
ne_win = tkinter.Toplevel(self.window)
win = test_win(ne_win)
else:
print("Data does not exist")
messagebox.showerror("ERROR", f'The user name or the id no exist \n Try again!')
def page():
window = tk.Tk()
Login(window)
window.mainloop()
if __name__ == '__main__':
page()
Test.py
from tkinter import Label, Toplevel
win = Toplevel()
win.geometry("300x300")
win.title("new window")
label1 = Label(win, text='Welcome')
label1.pack()

Related

Tkinter and SQlite project

from tkinter import *
from database import *
def Control_():
var1 = NameE.get()
var2 = LastnameE.get()
var3 = UsernameE.get()
var4 = PasswordE.get()
search = KullaniciAra(var3)
if search == None:
kullanici_ekle(var1,var2,var3,var4)
Login_Page()
else:
ErrorLabel = Label(win,text="This username is taken.")
ErrorLabel.grid(row=8,column=1)
def Login_Page():
def on_login():
var3 = UsernameE2.get()
var4 = PasswordE2.get()
search2 = KullaniciAra(var3)
if search2 == var4:
print("Done!")
win.destroy()
new_win = Tk()
new_win.title("T Messenger L")
new_win.geometry("200x200")
UsernameL2 = Label(new_win,text="Username",fg="black",bg="lightgray")
UsernameL2.grid(row=0,column=0)
UsernameE2 = Entry()
UsernameE2.grid(row=0,column=1)
PasswordL2 = Label(new_win,text="Password",fg="black",bg="lightgray")
PasswordL2.grid(row=1,column=0)
PasswordE2 = Entry()
PasswordE2.grid(row=1,column=1)
Button2 = Button(new_win,text="Login",command=on_login)
Button2.grid(row=2,column=1)
new_win.mainloop()
Tablo_olustur()
win = Tk()
win.title("T Messenger R")
win.geometry("200x200")
NameL = Label(win,text="Name",fg="black",bg="lightgray")
NameL.grid(row=1,column=0)
NameE = Entry()
NameE.grid(row=1,column=1)
LastnameL = Label(win,text="Lastname",fg="black",bg="lightgray")
LastnameL.grid(row=2,column=0)
LastnameE = Entry()
LastnameE.grid(row=2,column=1)
UsernameL = Label(win,text="Username",fg="black",bg="lightgray")
UsernameL.grid(row=3,column=0)
UsernameE = Entry()
UsernameE.grid(row=3,column=1)
PasswordL = Label(win,text="Password",fg="black",bg="lightgray")
PasswordL.grid(row=4,column=0)
PasswordE = Entry()
PasswordE.grid(row=4,column=1)
theLabel = Label(win,text="Login here",fg="blue",cursor="hand2",font=("TkDefaultFont",12,"underline"))
theLabel.grid(row=5,column=1)
theLabel.bind("<Button-1>", lambda event: Login_Page())
Button1 = Button(win,text="Register",command=Control_)
Button1.grid(row=6,column=1)
win.mainloop()
I wanted to make "login here" text with .bind() it worked as I want, it opened Login_Page() then even If I enter correct username and password when I click "Login" button nothing happens. What I want is "When 'login' button clicked and if username and password on my database and true open new page" and the new page name will be Vote_Page() cause user will choose like Find user, Update password, Delete acc etc
When writing a dialog box, you should use a Toplevel window as its base, not Tk. There should onle be one Tk instance in your program.
The implementation of FileDialog in cpython/filedialog.py is a nice example of how to implement a dialog in a class.

How do I call a variable from one class to another?

Im trying to display the variable that was in my login class to my menu class but whenever I do so I always get the error Object login has no attribute user.
Here is my login.py file
def login(self):
global con
user = self.txt_user.get().strip()
pwd = self.txt_pass.get().strip()
if user == "" or pwd == "":
messagebox.showerror("Error", "Please fill up all fields!")
else:
try :
con=pymysql.connect(host="localhost",user="root",password="",database="employee")
cur=con.cursor()
cur.execute("select 1 from employeelist where username=%s and password=%s", (user,pwd))
if cur.rowcount == 1:
messagebox.showinfo("Success", "Login Successful", parent=self.root)
self.menu()
else:
messagebox.showerror("Error", "Wrong Username or Password. Please try again!")
except Exception as ex:
messagebox.showerror("Error",f"Error due to: {str(ex)}",parent=self.root)
finally:
con.close()
def menu(self):
self.root.destroy()
menu.MenuForm()
if __name__ == "__main__":
root = Tk()
obj = Login(root)
root.mainloop()
Here is my menu.py file
from tkinter import *
from tkinter import ttk, messagebox
import PIL
from PIL import ImageTk
from PIL import Image
import login
class Menu:
def __init__(self,root):
self.root = root
self.root.title("Main Menu")
self.root.geometry("1350x768+0+0")
self.root.resizable(False, False)
self.bg = ImageTk.PhotoImage(file="Images/bgimage.jpg")
bg = Label(self.root, image=self.bg).place(x=0, y=0, relwidth=1, relheight=1)
framemenu = Frame(self.root, bg="white")
framemenu.place(x=350, y=100, height=500, width=700)
welcometitle = Label(framemenu, text="Welcome " + login.Login.user(), font=("Arial", 30, "bold"), fg="orange", bg="white").place(x=70,y=70)
def MenuForm():
win = Tk()
obj = Menu(win)
if __name__ == "__main__":
root = Tk()
obj = Menu(root)
root.mainloop()
I have imported login in my menu class but it still gives me the error object has no instance.
You can follow #Hosseinreza's approach to improve your code but if you want to work with your existing code then pass the user attribute to the menu class like below code excerpts
def login(self)
if cur.rowcount == 1:
messagebox.showinfo("Success", "Login Successful", parent=self.root)
self.menu(user)
def menu(self, user):
self.root.destroy()
menu.MenuForm(user)
then in Menu class, you can use it as below:
from tkinter import *
from tkinter import ttk, messagebox
import PIL
from PIL import ImageTk
from PIL import Image
class Menu:
def __init__(self,root, user):
self.root = root
self.root.title("Main Menu")
self.root.geometry("1350x768+0+0")
self.root.resizable(False, False)
self.bg = ImageTk.PhotoImage(file="Images/bgimage.jpg")
bg = Label(self.root, image=self.bg).place(x=0, y=0, relwidth=1, relheight=1)
framemenu = Frame(self.root, bg="white")
framemenu.place(x=350, y=100, height=500, width=700)
welcometitle = Label(framemenu, text="Welcome " + user, font=("Arial", 30, "bold"), fg="orange", bg="white").place(x=70,y=70)
def MenuForm(user):
win = Tk()
obj = Menu(win, user)
if __name__ == "__main__":
root = Tk()
obj = Menu(root)
root.mainloop()
Better pass the user to menu.MenuForm() via argument instead:
class Login:
...
def login(self):
user = self.txt_user.get().strip()
pwd = self.txt_pass.get().strip()
if user == "" or pwd == "":
messagebox.showerror("Error", "Please fill up all fields!")
else:
try :
con=pymysql.connect(host="localhost",user="root",password="",database="employee")
cur=con.cursor()
cur.execute("select 1 from employeelist where username=%s and password=%s", (user,pwd))
if cur.rowcount == 1:
messagebox.showinfo("Success", "Login Successful", parent=self.root)
self.menu(user) # pass user to self.menu()
else:
messagebox.showerror("Error", "Wrong Username or Password. Please try again!")
except Exception as ex:
messagebox.showerror("Error",f"Error due to: {str(ex)}",parent=self.root)
finally:
con.close()
def menu(self, user):
self.root.destroy()
menu.MenuForm(user) # pass user to menu.MenuForm()
menu.py:
from tkinter import *
#from tkinter import ttk, messagebox
from PIL import Image, ImageTk
class Menu:
def __init__(self, root, user): # user passed as argument
self.root = root
self.root.title("Main Menu")
self.root.geometry("1350x768+0+0")
self.root.resizable(False, False)
self.bg = ImageTk.PhotoImage(file="Images/bgimage.jpg")
bg = Label(self.root, image=self.bg).place(x=0, y=0, relwidth=1, relheight=1)
framemenu = Frame(self.root, bg="white")
framemenu.place(x=350, y=100, height=500, width=700)
welcometitle = Label(framemenu, text="Welcome " + user, font=("Arial", 30, "bold"), fg="orange", bg="white").place(x=70,y=70)
def MenuForm(user): # user passed as argument
win = Tk()
obj = Menu(win, user) # pass user to `Menu` class
if __name__ == "__main__":
root = Tk()
obj = Menu(root, "user")
root.mainloop()
Importing is not enough.
When you are working with objects , if you wanna use an object first of all you have to make an instance then you can work with the instance , here's an example:
class login():
def __init__(self):
print("Hi im Login Object")
class main():
def __init__(self):
login_obj = login() # Instance created
main()
As you see I made an instance of class Login into main class then it Worked.
Output:
Hi im Login Object

defined code executes before called upon using tkinter button [duplicate]

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 2 years ago.
I am working on a program that lets users store their usernames and passwords, and hashes the plaintext where they are stored (hence the commented out hashing code). However, I am using tkinter for the GUI, and one of my buttons runs a defined function before it's called. (ignore all seemingly random comments please)
import basehash
import tkinter
import tkinter as tk
import os
from tkinter import*
from tkinter import messagebox
from string import ascii_lowercase
userPaths = ['./usernames2.txt', './username.txt', './usernames3.txt']
passPaths = ['./Passwords2.txt', './Passwords.txt', './Passwords3.txt']
#create new doc and assign doc array
# use an array for password of paths where the password is stored on a plaintext file
password = ("test")
usernameguess1 = ("")
passwordguess1 = ("")
loggedin = 0
activeUser = ""
activeUserNum = 0
hashbase = basehash.base52()
LETTERS = {letter: str(index) for index, letter in enumerate(ascii_lowercase, start=1)}
def alphabet_position(text):
text = text.lower()
numbers = [LETTERS[character] for character in text if character in LETTERS]
return ''.join(numbers)
def loginpage():
#Gui Formatting
root = tkinter.Toplevel()
root.resizable(width=FALSE, height=FALSE)
root.title("HasherTest_V0.1 Login")
root.geometry("300x150")
#Username and password boxes
usernametext = tkinter.Label(root, text="Username:")
usernameguess = tkinter.Entry(root)
passwordtext = tkinter.Label(root, text="Password:")
passwordguess = tkinter.Entry(root, show="*")
usernameguess1 = usernameguess
def trylogin():
print ("Logging In...")
for x in range(0,len(userPaths)):
#get path data here
file1 = open(userPaths[x], "r")
original = file1.read()
file1.close()
if original == usernameguess.get():
userPaths[x] = activeUser
x = activeUserNum
file1 = open(passPaths[activeUserNum], "r")
original = file1.read()
original = hashbase.unhash(original)
file1.close()
if usernameguess.get() == activeUser and alphabet_position(passwordguess.get()) == original:
print ("Success!")
messagebox.showinfo("Success ", "Successfully logged in.")
viewbutton = tkinter.Button(root, text="Veiw Saved Passwords", command=lambda:[root.withdraw()])
viewbutton.pack()
else:
print ("Error: (Incorrect value entered)")
messagebox.showinfo("Error", "Sorry, but your username or password is incorrect. Try again")
#login button
def viewtest():
if loggedin == 1:
messagebox.showinfo("Success ", "Loading Passwords")
else:
messagebox.showinfo("Error", "You need to sign in first!")
#login button
root.deiconify() #shows login window
attemptlogin = tkinter.Button(root, text="Login", command=trylogin)
attemptview = tkinter.Button(root, text="View Stored Passwords", command=viewtest)
usernametext.pack()
usernameguess.pack()
passwordtext.pack()
passwordguess.pack()
attemptlogin.pack()
attemptview.pack()
window.mainloop()
def signuppage():
root2 = tkinter.Toplevel()
root2.resizable(width=FALSE, height=FALSE)
root2.title("HasherTest_V0.1 Login")
root2.geometry("300x150")
#Gui Formatting (again)
root2 = tkinter.Tk()
root2.resizable(width=FALSE, height=FALSE)
root2.title("HasherTest_V0.1")
root2.geometry("300x150")
#Username and password boxes
masterusername = tkinter.Label(root2, text="Enter Master Username:")
masterusernamebox = tkinter.Entry(root2)
masterpassword = tkinter.Label(root2, text="Enter Master Password:")
masterpasswordbox = tkinter.Entry(root2, show="*")
def trysignup():
newuser = str(masterusernamebox.get())
length = len(userPaths)
namepath = './usernames3.txt'
userPaths[length-1] = namepath
newfile = open(namepath, 'w')
newfile.write(newuser)
newfile.close()
password = str(masterpasswordbox.get())
numPass = alphabet_position(password)
print(numPass)
"""hashbase = basehash.base52()
#not taking numPass as an int
#run test 328-i
hashval = hashbase.hash(numPass)
print(hashval)
unhashed = hashbase.unhash(hashval)
print(unhashed)"""
path = './passwords3.txt'
newfile = open(path, 'w')
newfile.write(numPass)
newfile.close()
if newuser == "":
messagebox.showinfo("Error code 0", "No input entered")
else:
return
#login button
mastersignupbutton = tkinter.Button(root2, text="Sign Up 1", command=trysignup())
mastersignupbutton.pack()
masterusername.pack()
masterusernamebox.pack()
masterpassword.pack()
masterpasswordbox.pack()
window.mainloop()
window = tkinter.Tk()
window.resizable(width=FALSE, height=FALSE)
window.title("HasherTest_V0.1")
window.geometry("300x150")
loginbutton = tkinter.Button(window, text="Login", command=lambda:[window.withdraw(), loginpage()])
signupbutton = tkinter.Button(window, text="Sign Up", command=lambda:[window.withdraw(), signuppage()])
loginbutton.pack()
signupbutton.pack()
window.mainloop()
If you run this code, and press the sign up button, then type in a master username and password, it should write them both to a notepad file, and if there is nothing in the box, give an error message. However, neither of these functions are working. When the user presses the first "sign up" button on the main window, it runs the wrong code (somehow) and gives an error code before it should. the error code should show if there is nothing there when "sign up 1" button is pressed on the "enter master username and password" window. I have no clue why the code runs early. Could somebody please reply with the reason why, or even some fixed code? thanks, Tf0R24.
When creating a button, a common error is including the parentheses after the function name. Instead of this:
mastersignupbutton = tkinter.Button(root2, text="Sign Up 1", command=trysignup())
Do this:
mastersignupbutton = tkinter.Button(root2, text="Sign Up 1", command=trysignup)
which is exactly the same but without the parentheses after command=trysingup. If you want to call a function that requires arguments, do this:
tkinter.Button(master, text="text", command=lambda: function_that_requires_arguments(x, y))
change to
mastersignupbutton = tkinter.Button(root2, text="Sign Up 1", command=trysignup)

How to create password system in tkinter reading the data from file

I want to create password system in tkinter with notepad as my DB which contains the data in my working directory but when I insert data in the entry fields I receive an error login failed.Have created the txt file but it seems the function can't read from the file.Any suggestion on how to do this.
import tkinter as tk
import sys
from tkinter import messagebox
now = open("passdoc.txt","w+")
now.write("user\n")
now.write("python3")
now.close()
def login_in():
with open("passdoc.txt") as f:
new = f.readlines()
name = new[0].rstrip()
password = new[1].rstrip()
if entry1.get() == new[0] in passdoc.txt and entry2.get() == new[1] in
passdoc.txt:
root.deiconify()
log.destroy()
else:
messagebox.showerror("error","login Failed")
def close():
log.destroy() #Removes toplevel window
root.destroy() #Removes root window
sys.exit() #Ends the script
root=tk.Tk()
log = tk.Toplevel() #
root.geometry("350x350")
log.geometry("200x200")
entry1 = tk.Entry(log) #Username entry
entry2 = tk.Entry(log) #Password entry
button1 = tk.Button(log, text="Login", command=login_in) #Login button
button2 = tk.Button(log, text="Cancel", command=close) #Cancel button
label1 = tk.Label(root, text="tkinter password system")
entry1.pack()
entry2.pack()
button1.pack()
button2.pack()
label1.place(x=30,y=300)
label = tk.Label(root, text="welcome").pack()
root.withdraw()
root.mainloop()
I created this functions too but all seems not to work out for me
def login_in():
with open("passdoc.txt") as f:
new = f.readlines()
name = new[0].rstrip()
password = new[1].rstrip()
if entry1.get() == name in passdoc.txt and entry2.get() == password in
passdoc.txt:
root.deiconify()
log.destroy()
else:
messagebox.showerror("errror","login failed") #error login failed
(corrections)
You have a few things in your code that need some work but the main issue is in your login_in() function.
Your if statement is all wrong. I am not sure why you wrote it the way you did but lets fix it.
Because you defined name = new[0].rstrip() and password = new[1].rstrip()
you can use name and password to verify if the user has enter the correct credentials.
So your if statement should look like this:
if entry1.get() == name and entry2.get() == password:
Your use of in passdoc.txt does not do anything and cannot work because passdoc.txt to python looks like an undefined variable and would fail on the if statement. Remember that you imported all the contents of passdoc.txt as f so you didn't create a variable named passdoc you created one named f for the with open() statement
If you wanted to shorten your code a little you could remove name and password variables and just write the if statement with new
So your login_in() function could look like either this:
def login_in():
with open("passdoc.txt") as f:
new = f.readlines()
name = new[0].rstrip()
password = new[1].rstrip()
if entry1.get() == name and entry2.get() == password:
root.deiconify()
log.destroy()
else:
messagebox.showerror("error","login Failed")
Or this:
def login_in():
with open("passdoc.txt") as f:
new = f.readlines()
if entry1.get() == new[0].rstrip() and entry2.get() == new[1].rstrip():
root.deiconify()
log.destroy()
else:
messagebox.showerror("error","login Failed")

How to write commands to terminal using tkinter?

I wanted to do something like , if i type something in textbox that command would get executed completely
like this
ie the ~Desktop should be displayed to write next command.
but with my code im getting this also there is an error
as you can see ls command gets executed half in second case
my code is
#!/usr/bin/python
import Tkinter
import subprocess
import tkMessageBox
from Tkinter import *
root = Tk()
class HackBar:
def __init__(self,master):
frame=Frame(master,width = 600,height = 250)
#frame.pack()
def printconsole(event):
print("hello dere ")
def retrieve_input(event):
input = self.Text.get("1.0",'end-1c')
#print(input)
#subprocess.call(input,shell=TRUE)
subprocess.Popen(input)
root.quit()
#root = Tk()
#print p.communicate()
self.button1 = Button(root,text = "Execute")
self.button1.bind("<Button-1>",retrieve_input);
self.button1.grid(row = 0,sticky = E)
self.button2 = Button(root,text = " Quit ")
self.button2.bind("<Button-1>",printconsole);
self.button2.grid(row = 1,sticky = E)
self.Text = Text(root,height =4)
self.Text.grid(row = 0,column = 1,rowspan=2)
menu = Menu(root)
def AboutDialog():
tkMessageBox.showinfo('About','For any issues or suggestion contact rushic24#gmail.com ')
root.config(menu = menu)
submenu1 = Menu(menu)
menu.add_cascade(label="Help",menu=submenu1)
submenu1.add_command(label = "About",command = AboutDialog)
b = HackBar(root)
root.mainloop()
i think i need to use the root.quit() and would again need to start root ,
but it is giving the above error.
Any alternate method would also work.

Categories