When I run my login page and click the sign up button, it does not redirect to the register page but it just maintains at the login page
import register
import pymysql
class Login:
def __init__(self,root):
self.root=root
self.root.title("Scheduling Management System")
self.root.geometry("1350x768+0+0")
self.root.resizable(False,False)
self.txt_user = StringVar()
self.txt_pass = StringVar()
self.bg = ImageTk.PhotoImage(file = "Images/bgimage.jpg")
bg = Label(self.root,image=self.bg).place(x = 0, y= 0, relwidth = 1, relheight = 1)
framelogin = Frame(self.root,bg="white")
framelogin.place(x=450,y=100,height=500,width=700)
title=Label(framelogin,text="Login Here",font=("Arial",30,"bold"),fg="orange",bg="white").place(x=90,y=30)
nexttitle=Label(framelogin,text="Scheduling Staff System",font=("Times New Roman",18,"bold"),fg="orange",bg="white").place(x=90,y=100)
userlabel=Label(framelogin,text="Username",font=("Arial",15,"bold"),fg="gray",bg="white").place(x=90,y=140)
self.txt_user=Entry(framelogin,textvariable = self.txt_user,font=("times new roman",15),bg="lightgray")
self.txt_user.place(x=90,y=170,width=350,height=35)
passlabel=Label(framelogin,text="Password",font=("Arial",15,"bold"),fg="gray",bg="white").place(x=90,y=210)
self.txt_pass=Entry(framelogin,textvariable = self.txt_pass,font=("times new roman",15),show="*",bg="lightgray")
self.txt_pass.place(x=90,y=240,width=350,height=35)
forget=Button(framelogin,text="Forgot Password",bg="white",fg="orange",font=("trebuchet ms",12)).place(x=90,y=305)
reglabel=Label(framelogin,text="Don't Have an Account?",font=("trebuchet ms",12,"bold"),fg="orange",bg="white").place(x=320,y=310)
registerbutton=Button(framelogin,text="Sign Up",command=register,bg="white",fg="orange",font=("trebuchet ms",12)).place(x=510,y=305)
loginbutton=Button(framelogin,text="Login",command=self.login,fg="white",bg="orange",font=("sans serif ms",20)).place(x=90,y=350,width="100",height="40")
def login(self):
if self.txt_user.get() == "" or self.txt_pass.get() == "":
messagebox.showerror("Error", "Please fill up all fields!")
root = Tk()
obj = Login(root)
root.mainloop()
Here is my register page
from tkinter import *
from tkinter import ttk, messagebox
import PIL
import pymysql
from PIL import ImageTk
from PIL import Image
class Register:
def __init__(self, root):
self.root = root
self.root.title("Registration Page")
self.root.geometry("1350x768+0+0")
self.root.config(bg="light blue")
self.bg = ImageTk.PhotoImage(file="Images/bgimage.jpg")
bg = Label(self.root,image=self.bg).place(x = 0, y= 0, relwidth = 1, relheight = 1)
frame1=Frame(self.root,bg="white")
frame1.place(x=450,y=100,width=700,height=600)
title=Label(frame1,text="Please enter your information here",font=("trebuchet ms",20,),bg="white",fg="black").place(x=50, y=30)
fname=Label(frame1,text="First Name",font=("times new roman",15,"bold"),bg="white",fg="black").place(x=50, y=100)
self.text_fname=Entry(frame1,font=("arial",15,),bg="lightgray")
self.text_fname.place(x=50, y=130, width=250)
lname=Label(frame1,text="Last Name",font=("times new roman",15,"bold"),bg="white",fg="black").place(x=370, y=100)
self.text_lname=Entry(frame1,font=("arial",15,),bg="lightgray")
self.text_lname.place(x=370, y=130, width=250)
contact=Label(frame1,text="Contact Number",font=("times new roman",15,"bold"),bg="white",fg="black").place(x=50, y=170)
self.text_contact=Entry(frame1,font=("arial",15,),bg="lightgray")
self.text_contact.place(x=50, y=200, width=250)
email=Label(frame1,text="Email Address",font=("times new roman",15,"bold"),bg="white",fg="black").place(x=370, y=170)
self.text_email=Entry(frame1,font=("arial",15,),bg="lightgray")
self.text_email.place(x=370, y=200, width=250)
question=Label(frame1,text="Security Question",font=("times new roman",15,"bold"),bg="white",fg="black").place(x=50, y=240)
self.cmbquestion=ttk.Combobox(frame1,font=("times new roman",13),state='readonly',justify=CENTER)
self.cmbquestion['values']=("Select","Your First Car","Your Mothers First Name", "Your Best Friend Name")
self.cmbquestion.place(x=50, y=270, width=250)
self.cmbquestion.current(0)
answer=Label(frame1,text="Answer",font=("times new roman",15,"bold"),bg="white",fg="black").place(x=370, y=240)
self.text_answer=Entry(frame1,font=("arial",15,),bg="lightgray")
self.text_answer.place(x=370, y=270, width=250)
pwd=Label(frame1,text="Password",font=("times new roman",15,"bold"),bg="white",fg="black").place(x=50, y=310)
self.text_pwd=Entry(frame1,font=("arial",15,),show="*",bg="lightgray")
self.text_pwd.place(x=50, y=340, width=250)
cfmpwd=Label(frame1,text="Confirm Password",font=("times new roman",15,"bold"),bg="white",fg="black").place(x=370, y=310)
self.text_cfmpwd=Entry(frame1,font=("arial",15,),show="*",bg="lightgray")
self.text_cfmpwd.place(x=370, y=340, width=250)
self.btn= ImageTk.PhotoImage(file="images/register.png")
btn = Button(frame1,image=self.btn, bd=0, command = self.registerdata,cursor = "hand2").place(x=50, y = 420)
def registerdata(self):
if self.text_fname.get()=="" or self.text_lname.get()=="" or self.text_contact.get()=="" or self.text_email.get()=="" or self.cmbquestion.get()=="Select" or self.text_pwd.get()=="" or self.text_cfmpwd.get()=="":
messagebox.showerror("Error","All fields are required!",parent=self.root)
elif self.text_pwd.get()!=self.text_cfmpwd.get():
messagebox.showerror("Error","Passwords must be the same!",parent=self.root)
else:
try:
con=pymysql.connect(host="localhost",user="root",password="",database="employee")
cur=con.cursor()
cur.execute("select * from employeelist where email=%s", self.text_email.get())
row=cur.fetchone()
print(row)
if row!=None:
messagebox.showerror("Error","User Already Exists. Please Register With a New Email",parent=self.root)
else:
cur.execute("insert into employeelist (fname,lname,contact,email,question,answer,password) values(%s,%s,%s,%s,%s,%s,%s)",
(self.text_fname.get(),self.text_lname.get(),self.text_contact.get(),self.text_email.get(),self.cmbquestion.get(),self.text_answer.get(),self.text_pwd.get()))
con.commit() #do changes to database
con.close()
messagebox.showinfo("Success","Registration Successful",parent=self.root)
except Exception as ex:
messagebox.showerror("Error",f"Error due to: {str(ex)}",parent=self.root)
root = Tk()
obj = Register(root)
root.mainloop()
I have inserted the action for the button as command = register but it is still not redirecting to the register page. Is there any error with my command function?
Better move the main block code inside register.py in a function:
class Register:
...
def RegisterForm():
win = Toplevel()
obj = Register(win)
Then you can use this function inside the login page:
import register
...
class Login:
def __init__(self):
...
Button(framelogin,text="Sign Up",command=self.register,bg="white",fg="orange",font=("trebuchet ms",12)).place(x=510,y=305)
...
def register(self):
register.RegisterForm()
Here I made a registration frame on the main window/frame and raised it above all existing frames.Then when submit button is pressed that frame gets destroyed.
class login:
def __init__(self):
button=tk.Button(command=self.register)
def register(self):
f1=tk.Frame(root)
f1.tkraise()
boo=tk.Button(text='submit',command=f1.destroy)
I'm trying to setup a program where my tkinter GUI functions are in a class and my database functions are in another class. I have a function external to both classes that fails when I try to call a function within the DB class. Can you help me resolve this error? Should both my GUI and any database be in separate functions or is that a poor design. The attached code is a stripped down version to illustrates my issue. Clicking the "View all" button generates the error.
import sqlite3
from tkinter import *
from tkinter import messagebox
class DB:
def __init__(self):
self.conn = sqlite3.connect("mybooks.db")
self.cur = self.conn.cursor()
self.cur.execute(
"CREATE TABLE IF NOT EXISTS book (id INTEGER PRIMARY KEY, title TEXT, author TEXT, isbn INTEGER)")
self.conn.commit()
def __del__(self):
self.conn.close()
def view(self):
self.cur.execute("SELECT * FROM book")
rows = cur.fetchall()
return rows
def view_command():
# there is a problem with the next line
# when rows=DB.view() error is TypeError: view() missing 1 required positional argument: 'self'
# when rows=DB.view(self) error is NameError: name 'self' is not defined
rows=DB.view(self)
for row in rows:
print(row)
class App_GUI(): # create the main window
def __init__(self, master):
self.master = master
self.master.title("My Books")
self.master.l1 = Label(self.master, text="Title")
self.master.l1.grid(row=0, column=0)
self.master.l2 = Label(self.master, text="Author")
self.master.l2.grid(row=0, column=2)
self.master.l3 = Label(self.master, text="ISBN")
self.master.l3.grid(row=1, column=0)
self.master.title_text = StringVar()
self.master.e1 = Entry(self.master, textvariable=self.master.title_text)
self.master.e1.grid(row=0, column=1)
self.master.author_text = StringVar()
self.master.e2 = Entry(self.master, textvariable=self.master.author_text)
self.master.e2.grid(row=0, column=3)
self.master.isbn_text = StringVar()
self.master.e3 = Entry(self.master, textvariable=self.master.isbn_text)
self.master.e3.grid(row=1, column=1)
self.master.list1 = Listbox(self.master, height=6, width=35)
self.master.list1.grid(row=2, column=0, rowspan=6, columnspan=2)
self.master.sb1 = Scrollbar(self.master)
self.master.sb1.grid(row=2, column=2, rowspan=6)
self.master.list1.configure(yscrollcommand=self.master.sb1.set)
self.master.sb1.configure(command=self.master.list1.yview)
self.master.b1 = Button(self.master, text="View all", width=12, command=view_command)
self.master.b1.grid(row=2, column=3)
self.master.b6 = Button(self.master, text="Close", width=12, command=self.master.destroy)
self.master.b6.grid(row=7, column=3)
return
###############################
# Program Main #
###############################
def main():
db = DB()
root = Tk()
def on_closing():
dd = db
if messagebox.askokcancel("Quit", "Do you want to close the application"): # ask the user if he/she wants to close the application
root.destroy()
del dd
root.protocol("WM_DELETE_WINDOW", on_closing) # catch the user closing the window
app = App_GUI(root) # creation of an instance
root.mainloop() # tkinter mainloop
if __name__ == '__main__':
main()
````
You need to pass db to App_GUI and then on to the function:
def view_command(db):
rows = db.view()
for row in rows:
print(row)
class App_GUI(): # create the main window
def __init__(self, master, db):
# other stuff elided ...
self.master.b1 = Button(self.master, text="View all", width=12, command=lambda : view_command(db))
...
def main():
db = DB()
# other stuff elided
app = App_GUI(root, db)
edit: forgot to remove self.
I figured it out! In addition to your changes, I had to remove 'self' from rows=db.view(). Thanks for your help! Revised code:
import sqlite3
from tkinter import *
from tkinter import messagebox
class DB:
def __init__(self):
self.conn = sqlite3.connect("mybooks.db")
self.cur = self.conn.cursor()
self.cur.execute(
"CREATE TABLE IF NOT EXISTS book (id INTEGER PRIMARY KEY, title TEXT, author TEXT, isbn INTEGER)")
self.conn.commit()
def __del__(self):
self.conn.close()
def view(self):
self.cur.execute("SELECT * FROM book")
rows = self.cur.fetchall()
return rows
def view_command(db):
rows=db.view()
for row in rows:
print(row)
class App_GUI(): # create the main window
def __init__(self, master, db):
self.master = master
self.master.title("My Books")
self.master.l1 = Label(self.master, text="Title")
self.master.l1.grid(row=0, column=0)
self.master.l2 = Label(self.master, text="Author")
self.master.l2.grid(row=0, column=2)
self.master.l3 = Label(self.master, text="ISBN")
self.master.l3.grid(row=1, column=0)
self.master.title_text = StringVar()
self.master.e1 = Entry(self.master, textvariable=self.master.title_text)
self.master.e1.grid(row=0, column=1)
self.master.author_text = StringVar()
self.master.e2 = Entry(self.master, textvariable=self.master.author_text)
self.master.e2.grid(row=0, column=3)
self.master.isbn_text = StringVar()
self.master.e3 = Entry(self.master, textvariable=self.master.isbn_text)
self.master.e3.grid(row=1, column=1)
self.master.list1 = Listbox(self.master, height=6, width=35)
self.master.list1.grid(row=2, column=0, rowspan=6, columnspan=2)
self.master.sb1 = Scrollbar(self.master)
self.master.sb1.grid(row=2, column=2, rowspan=6)
self.master.list1.configure(yscrollcommand=self.master.sb1.set)
self.master.sb1.configure(command=self.master.list1.yview)
self.master.b1 = Button(self.master, text="View all", width=12, command=lambda : view_command(db))
self.master.b1.grid(row=2, column=3)
self.master.b6 = Button(self.master, text="Close", width=12, command=self.master.destroy)
self.master.b6.grid(row=7, column=3)
return
###############################
# Program Main #
###############################
def main():
db = DB()
root = Tk()
def on_closing():
dd = db
if messagebox.askokcancel("Quit", "Do you want to close the application"): # ask the user if he/she wants to close the application
root.destroy()
del dd
root.protocol("WM_DELETE_WINDOW", on_closing) # catch the user closing the window
app = App_GUI(root, db) # creation of an instance
root.mainloop() # tkinter mainloop
if __name__ == '__main__':
main()
I am using Python 3.x, and I'm trying to fetch Dataset records and display them in an extra Window. I'm a bloody beginner and currently I don't see my error. I've checked multiple threads but didn't get the solution. Debugging isn't helping me either.
Here's my approach:
import sqlite3
from tkinter import *
class Overview():
def __init__(self,master):
self.master = master
self.master.geometry('170x110+100+200')
self.master.title('Welcome!')
self.button1 = Button(self.master, text="Show dataset", fg='green', command=self.gotoMenu).grid(
row=1, column=1)
def gotoMenu(self):
# This is the Dataset GUI#
root2 = Toplevel(self.master)
myGUI = Menu(root2)
def main():
root = Tk()
overviewGUI = Overview(root)
root.mainloop()
if __name__ == '__main__':
main()
class Menu:
def __init__(self,master):
# This is the Dataset GUI#
self.connection = sqlite3.connect('test.db')
print("Opened database successfully")
self.cur = self.connection.cursor()
self.master = master
self.master.title('Dataset')
self.master.geometry("320x240")
print("GUI created")
self.dateLabel = Label(self.master, text="Date", width=10)
self.dateLabel.grid(row=0, column=0)
self.BMILabel = Label(self.master, text="Name", width=10)
self.BMILabel.grid(row=0, column=1)
self.stateLabel = Label(self.master, text="ID", width=10)
self.stateLabel.grid(row=0, column=2)
self.insertDS('random')
self.showallrecords()
def showallrecords(self):
data = self.readfromdatabase()
for index, dat in enumerate(data):
Label(self.master, text=dat[2]).grid(row=index + 1, column=0)
Label(self.master, text=dat[1]).grid(row=index + 1, column=1)
Label(self.master, text=dat[0]).grid(row=index + 1, column=2)
def readfromdatabase(self):
self.cur.execute("SELECT * FROM LOGGING")
return self.cur.fetchall()
def createTable(self):
try:
self.connection.execute(
"CREATE TABLE LOGGING(ID INTEGER PRIMARY KEY AUTOINCREMENT,NAME TEXT NOT NULL, TIMESTAMP DATE DEFAULT (datetime('now','localtime')));")
print("Table created successfully")
except:
print("Table already exists")
def insertDS(self, name):
self.connection.execute("INSERT INTO LOGGING (NAME) \
VALUES (?);", [name])
self.connection.commit()
print("Records created successfully")
My Application should start with the "Overview" GUI, on button click I want to see all fetched Datasets from "Menu" Class.
However, after clicking the button the next window is empty and has the title "Welcome" which should be "Dataset"
UPDATE:
I am getting no error, BUT my fetched results won't show in the 2nd Window, and the title isn't self.master.title('Dataset') as initialized in class Menu.
I feel like it's just creating some empty Window without even looking in my Menu Class?
Solution:
python className not defined NameError
Somehow(can't explain why) when I moved the ´name´ block down with the def (even though indentions were right) it worked.
You have overloaded Menu, change your class name by an another name.
And don't use import *
Working on a group program that has users and passwords. We are trying to insert our users and passwords via python to sqlite. But atm we are only sending blank data before our graphic window pops up with a button that is supposed to send the data. We have tried different variations found on multiple websites but nothing seems to work.
from tkinter import *
import sqlite3
import sys
conn = sqlite3.connect('indexCards.db')
cur = conn.cursor()
users ={}
def addUser(entUsername, entPassword):
#global entUsername, entPassword
NAME = entUsername.get()
PASSWORD = entPassword.get()
print("add User") #this is testing only
print(NAME, PASSWORD) # this is testing to see the passed variable
//
//This is where we are having the issues
conn.executemany('INSERT INTO USER(NAME,PASSWORD)\
VALUES (? ,?);', [(NAME,PASSWORD)])
conn.commit();
return (NAME, PASSWORD)
def makeWindow():
global entUsername, entPassword
window = Tk()
window.title('Add New User')
lblInst = Label(window, text = "Create your account here:", font=("Helvetica",16))
lblInst.pack()
lblUsername = Label(window, text="Please enter a username: ")
entUsername = Entry(window)
lblUsername.pack()
entUsername.pack()
lblPassword = Label(window, text="Please enter a password: ")
entPassword = Entry(window)
lblPassword.pack()
entPassword.pack()
btn = Button(window, text="Create", command=addUser(entUsername, entPassword))
btn.pack()
print (addUser(entUsername, entPassword))
print('entUsername', 'entPassword')
#window.mainloop()
return window
#if __name__ == '__main__':
# main():
window = makeWindow()
window.mainloop()
The problem is that you're calling the function immediately, before the user has a chance to enter any data.
See Why is Button parameter “command” executed when declared?
The reason it invokes the method immediately and pressing the button does nothing is that addUser(entUsername, entPassword) is evaluated and its return value is attributed as the command for the button. So if addUser prints something to tell you it has run and returns None, you just run addUser to evaluate its return value and given None as the command for the button.
To have buttons to call functions with different arguments you can use global variables, although I can't recommend it:
import sqlite3
from tkinter import *
conn = sqlite3.connect('indexCards.db')
cur = conn.cursor()
users = {}
cur = conn.cursor()
cur.execute('''
Create table if not exists USER(NAME varchar(100), PASSWORD varchar(100))
''')
def addUser():
NAME = entUsername.get()
PASSWORD = entPassword.get()
print("add User") # this is testing only
print(NAME, PASSWORD) # this is testing to see the passed variable
# This is where we are having the issues
conn.executemany('INSERT INTO USER(NAME,PASSWORD) VALUES (? ,?);', [(NAME, PASSWORD)])
conn.commit()
return (NAME, PASSWORD)
def makeWindow():
global entUsername
global entPassword
window = Tk()
window.title('Add New User')
lblInst = Label(window, text="Create your account here:", font=("Helvetica", 16))
lblInst.pack()
lblUsername = Label(window, text="Please enter a username: ")
entUsername = Entry(window)
lblUsername.pack()
entUsername.pack()
lblPassword = Label(window, text="Please enter a password: ")
entPassword = Entry(window)
lblPassword.pack()
entPassword.pack()
btn = Button(window, text="Create", command=addUser)
btn.pack()
print(addUser())
window.mainloop()
return window
window = makeWindow()
If you don't want to create global then you can pass the function with multiple arguments to an anonymous function i.e lambda function
btn = Button(window, text="Create", command= lambda : addUser(entUsername, entPassword))