Aug-28-2023, 07:21 PM
Just a simple login system. It's not complete, still have some details to work on and after maybe make a generic page class as I have some repeating code.
# Do the imports import tkinter as tk from tkinter import font import sqlite3 as sq import os # Executed from bash shell or vscode - vscode default path = os.path.dirname(os.sys.argv[0]) if not path: path = '.' class Database: ''' Database class handles all methods for the adding, deleting, and retrieving information ''' def __init__(self): ''' Setup the sqlite3 database and cursor ''' self.db = sq.connect(f'{path}/customer.db') self.cursor = self.db.cursor() def create(self): ''' create creates the table and sets up a basic email validation ''' query = ''' create table if not exists customer ( id integer primary key, name text not null, email text unique not null, password text not null, logged_in integer not null default 0 check( email like '%_@_%._%' and length(email) - length(replace(email, '@', '')) = 1 and substr(lower(email), 1, instr(email, '.') - 1) not glob '*[^@0-9a-z]*' and substr(lower(email), instr(email, '.') + 1) not glob '*[^a-z]*' )) ''' # Execute and commit the query self.db.execute(query) self.db.commit() def add(self, name, email, password): ''' Method add data to the database and handles some error checking ''' query = ''' insert into customer (name, email, password) values (?,?,?) ''' try: self.cursor.execute(query, (name.lower().strip(), email.lower().strip(), password)) self.db.commit() return ' Added user to database.' except sq.OperationalError as error: return error except sq.IntegrityError as error: if 'constraint' in str(error) and 'customer.email' in str(error): return 'That email already exists. Please try again.' elif 'CHECK' in str(error): return 'That is not a valid email. Please try again.' else: return 'An unknown error has occurred' def remove(self, id): ''' Method for removing users by id ''' if id: self.cursor.execute(f'delete from customer where id = {id}') def getall(self): ''' Method gets all information from database ''' return self.cursor.execute('select * from customer').fetchall() def getone(self, id): ''' Method gets information for a single id ''' if id: return self.cursor.execute(f'select * from customer where id = {id}').fetchone() def login(self, email, password): ''' Method checks if a user is in the database based on email and password if a user is found then it will set a session variable for being logged in. ''' query = f''' select id, email, password from customer where email = "{email}" and password = "{password}" ''' res = self.cursor.execute(query).fetchone() if res: self.update(res[0], 1) return True return False def update(self, id, log=int(0)): ''' Helper method for above method. Set the logged_in field to 1 ''' self.cursor.execute(f'update customer set logged_in = {log} where id = {id}') def logout(self, id, log=int(0)): ''' Method for logging out. Sets the logged_in field to 0 ''' self.cursor.execute(f'update customer set logged_in = {log} where id = {id}') class Window: ''' Window class is the main display window ''' def __init__(self, parent): self.parent = parent parent.title('Main Page') parent.columnconfigure(0, weight=1) parent.rowconfigure(0, weight=1) parent.update() width = parent.winfo_reqwidth() * 3 # Container frame for holding all widgets container = tk.Frame(parent, bg='#555555') container.grid(column=0, row=0, sticky='news') container.grid_columnconfigure(0, weight=3) # Simple header label header = tk.Label(container, text='Main Page') header['font'] = ('cursive', 30, 'bold') header['bg'] = '#333333' header['fg'] = 'whitesmoke' header['relief'] = 'solid' header['borderwidth'] = 1 header.grid(column=0, row=0, sticky='new', ipady=10) # The container holds all our links link_container = tk.Frame(container, bg='white') link_container.grid(column=0, row=1, sticky='new') # Create our links using labels. Bind links to give a hover effect self.login_label = tk.Label(link_container, text='Login', fg='blue', bg='white', cursor='hand2') self.login_label['font'] = (None, 12, 'normal') self.login_label.grid(column=0, row=0, padx=5, pady=5) self.login_label.bind('<Enter>', lambda label: self.link_on(self.login_label)) self.login_label.bind('<Leave>', lambda label: self.link_off(self.login_label)) self.logout_label = tk.Label(link_container, text='Logout', fg='blue', bg='white', cursor='hand2') self.logout_label['font'] = (None, 12, 'normal') self.logout_label.grid(column=1, row=0, padx=5, pady=5) self.logout_label.bind('<Enter>', lambda label: self.link_on(self.logout_label)) self.logout_label.bind('<Leave>', lambda label: self.link_off(self.logout_label)) self.register_label = tk.Label(link_container, text='Register', fg='blue', bg='white', cursor='hand2') self.register_label['font'] = (None, 12, 'normal') self.register_label.grid(column=2, row=0, padx=5, pady=5) self.register_label.bind('<Enter>', lambda label: self.link_on(self.register_label)) self.register_label.bind('<Leave>', lambda label: self.link_off(self.register_label)) self.exit_label = tk.Label(link_container, text='Exit', fg='tomato', bg='white', cursor='hand2') self.exit_label['font'] = (None, 14, 'normal') self.exit_label.grid(column=3, row=0, padx=(width,10), pady=5) self.exit_label.bind('<Enter>', self.exit_enter) self.exit_label.bind('<Leave>', self.exit_leave) self.log = tk.Label(container, text='Your are logged out', bg='#555555', fg='#cecece', anchor='e', padx=5) self.log['font'] = (None, 12, 'bold') self.log.grid(column=0, row=2, padx=5, pady=5, sticky='new') # These methods provide the hover effects def link_on(self, label): label['fg'] = 'orangered' def link_off(self, label): label['fg'] = 'blue' def exit_enter(self, event): self.exit_label['fg'] = 'red' def exit_leave(self, event): self.exit_label['fg'] = 'tomato' class LoginForm: ''' This class contains our login form''' def __init__(self, parent): self.parent = parent def form(self): self.window = tk.Toplevel(None) self.window.minsize(800,600) self.window['padx'] = 3 self.window['pady'] = 3 self.window.title('A Login Form') self.window.columnconfigure(0, weight=1) self.window.rowconfigure(0, weight=1) self.window['bg'] = '#333333' container = tk.Label(self.window, bg='#555555') container.grid(column=0, row=0, sticky='news') container.grid_columnconfigure(0, weight=3) # Simple header label header = tk.Label(container, text='Login Page') header['font'] = ('cursive', 30, 'bold') header['bg'] = '#333333' header['fg'] = 'whitesmoke' header['relief'] = 'solid' header['borderwidth'] = 1 header.grid(column=0, row=0, sticky='new', ipady=10) self.button = tk.Button(self.window, text='Cancel', bg='tomato', fg='black', cursor='hand2') self.button['font'] = (None, 12, 'normal') self.button['command'] = self.close self.button['highlightbackground'] = 'black' self.button['highlightcolor'] = 'black' self.button.grid(column=0, row=1) self.button.bind('<Enter>', self.on_enter) def close(self): ''' Method for destroying the form window and retreiving the main window ''' self.window.destroy() self.parent.deiconify() def on_enter(self, event): # method for hover effect of the cancel button self.button['activebackground'] = 'orangered' self.button['activeforeground'] = 'white' class RegisterForm: ''' This class contains the registraion form ''' def __init__(self, parent): self.parent = parent def form(self): self.window = tk.Toplevel(None) self.window.minsize(800,600) self.window['padx'] = 3 self.window['pady'] = 3 self.window.title('Registation Form') self.window.columnconfigure(0, weight=1) self.window.rowconfigure(0, weight=1) self.window['bg'] = '#333333' container = tk.Label(self.window, bg='#555555') container.grid(column=0, row=0, sticky='news') container.grid_columnconfigure(0, weight=3) # Simple header label header = tk.Label(container, text='Registration Page') header['font'] = ('cursive', 30, 'bold') header['bg'] = '#333333' header['fg'] = 'whitesmoke' header['relief'] = 'solid' header['borderwidth'] = 1 header.grid(column=0, row=0, sticky='new', ipady=10) self.button = tk.Button(self.window, text='Cancel', bg='tomato', fg='black', cursor='hand2') self.button['font'] = (None, 12, 'normal') self.button['command'] = self.close self.button['highlightbackground'] = 'black' self.button['highlightcolor'] = 'black' self.button.grid(column=0, row=1) self.button.bind('<Enter>', self.on_enter) def close(self): ''' Method for destroying the form window and retreiving the main window ''' self.window.destroy() self.parent.deiconify() def on_enter(self, event): # method for hover effect of the cancel button self.button['activebackground'] = 'orangered' self.button['activeforeground'] = 'white' def update(self): pass class Controller: ''' Controller class will handle all communications between the other classes ''' def __init__(self, db, window, loginform, registerform): # setup some class variables self.db = db self.window = window self.loginform = loginform self.registerform = registerform self.session = 0 # Window Link Commands self.window.login_label.bind('<Button-1>', lambda event: self.login()) self.window.logout_label.bind('<Button-1>', lambda event: self.logout()) self.window.register_label.bind('<Button-1>', lambda event: self.register()) self.window.exit_label.bind('<Button-1>', lambda event: self.window_exit()) def login(self): ''' Method for getting the login form ''' self.window.parent.withdraw() self.loginform.form() self.window.log['text'] = 'Your logged in' self.window.log['fg'] = 'whitesmoke' def logout(self): ''' Method for logging out ''' self.db.logout(1) self.window.log['text'] = 'Your logged out' self.window.log['fg'] = '#cecece' def register(self): ''' Method for registering new user ''' self.window.parent.withdraw() self.registerform.form() def window_exit(self): ''' Method will log out user and exit program ''' self.db.logout(1) self.window.parent.destroy() if __name__ == '__main__': root = tk.Tk() root.minsize(800, 600) root['padx'] = 3 root['pady'] = 3 controller = Controller(Database(), Window(root), LoginForm(root), RegisterForm(root)) root.mainloop()
I welcome all feedback.
The only dumb question, is one that doesn't get asked.
My Github
How to post code using bbtags
Download my project scripts
The only dumb question, is one that doesn't get asked.
My Github
How to post code using bbtags
Download my project scripts