Important: When binding events, remember to include the event parameter in your callback function,
even if you don't use it. For example: def callback(event):
3. Validating User Input
Tkinter provides built-in validation for Entry widgets to ensure users enter valid data.
Using the validate and validatecommand Options
import tkinter as tk
from tkinter import messagebox
def validate_number(input):
if input.isdigit() or input == '': # Allow empty string for backspace
return True
elif input == '.':
return True
else:
return False
def on_submit():
if entry.get():
messagebox.showinfo("Success", f"You entered: {entry.get()}")
root = tk.Tk()
# Register the validation function
vcmd = (root.register(validate_number), '%P')
# Create and pack widgets
label = tk.Label(root, text="Enter a number:")
label.pack(pady=5)
entry = tk.Entry(
root,
validate='key',
validatecommand=vcmd
)
entry.pack(pady=5)
submit_btn = tk.Button(root, text="Submit", command=on_submit)
submit_btn.pack(pady=10)
root.mainloop()
Input Validation Demo
Please enter a valid number
Common Validation Types
%d - Action code (0=delete, 1=insert, -1=other)
%i - Index of the insertion/deletion
%P - Value of the entry if the edit is allowed
%s - Value of the entry before the edit
%S - The text string being inserted or deleted
%v - The current value of the widget's validate option
%V - The validation condition that triggered the callback
%W - The widget's name
4. Integrating Tkinter with SQLite
SQLite is a lightweight database that comes built-in with Python, making it perfect for Tkinter applications.
Basic Database Operations
import tkinter as tk
from tkinter import messagebox
import sqlite3
from sqlite3 import Error
def create_connection():
conn = None
try:
conn = sqlite3.connect('database.db')
return conn
except Error as e:
print(e)
return conn
def create_table(conn):
try:
cursor = conn.cursor()
cursor.execute('''
CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
email TEXT UNIQUE NOT NULL,
age INTEGER
)
''')
conn.commit()
except Error as e:
print(e)
def add_user():
name = name_entry.get()
email = email_entry.get()
age = age_entry.get()
if not name or not email:
messagebox.showerror("Error", "Name and email are required!")
return
try:
conn = create_connection()
cursor = conn.cursor()
cursor.execute('''
INSERT INTO users (name, email, age)
VALUES (?, ?, ?)
''', (name, email, age))
conn.commit()
messagebox.showinfo("Success", "User added successfully!")
clear_entries()
display_users()
except sqlite3.IntegrityError:
messagebox.showerror("Error", "Email already exists!")
except Error as e:
messagebox.showerror("Error", str(e))
finally:
if conn:
conn.close()
def display_users():
try:
conn = create_connection()
cursor = conn.cursor()
cursor.execute("SELECT * FROM users")
rows = cursor.fetchall()
# Clear the listbox
user_list.delete(0, tk.END)
# Add column headers
user_list.insert(tk.END, "ID\tName\tEmail\tAge")
user_list.insert(tk.END, "-" * 40)
# Add user data
for row in rows:
user_list.insert(tk.END, f"{row[0]}\t{row[1]}\t{row[2]}\t{row[3] if row[3] else 'N/A'}")
except Error as e:
messagebox.showerror("Error", str(e))
finally:
if conn:
conn.close()
def clear_entries():
name_entry.delete(0, tk.END)
email_entry.delete(0, tk.END)
age_entry.delete(0, tk.END)
# Create the main window
root = tk.Tk()
root.title("User Management System")
root.geometry("600x400")
# Create database and table if they don't exist
conn = create_connection()
if conn is not None:
create_table(conn)
conn.close()
# Create and pack widgets
tk.Label(root, text="Name:").pack(pady=5)
name_entry = tk.Entry(root, width=40)
name_entry.pack(pady=5)
tk.Label(root, text="Email:").pack(pady=5)
email_entry = tk.Entry(root, width=40)
email_entry.pack(pady=5)
tk.Label(root, text="Age:").pack(pady=5)
age_entry = tk.Entry(root, width=10)
age_entry.pack(pady=5)
add_btn = tk.Button(root, text="Add User", command=add_user)
add_btn.pack(pady=10)
# Create a listbox to display users
user_list = tk.Listbox(root, width=80, height=10)
user_list.pack(pady=10)
# Display existing users
display_users()
root.mainloop()
Database Operations in Tkinter:
Connection: Always open and close database connections properly
Error Handling: Use try-except blocks to handle database errors
Transactions: Use commit() to save changes and rollback() on errors
Security: Use parameterized queries to prevent SQL injection
5. CRUD Operations with Tkinter
Implementing Create, Read, Update, and Delete operations in a Tkinter application.
Example Database Table: Products
ID
Name
Price
Stock
Actions
1
Laptop
$999.99
15
2
Smartphone
$699.99
30
CRUD Operations Code Structure
# Create (Insert)
def create_product():
# Get values from entries
# Validate input
# Insert into database
# Refresh the view
pass
# Read (Select)
def read_products():
# Query all products
# Display in a listbox or treeview
pass
# Update
def update_product():
# Get selected product ID
# Get updated values
# Update database
# Refresh the view
pass
# Delete
def delete_product():
# Get selected product ID
# Confirm deletion
# Delete from database
# Refresh the view
pass
Best Practices:
Always validate user input before database operations
Use transactions for multiple related operations
Provide feedback to users after each operation
Handle exceptions and display user-friendly error messages
Consider using the Model-View-Controller (MVC) pattern for larger applications
Summary
In this lecture, we've covered:
Event Handling: Binding events to widgets and handling user interactions
Input Validation: Ensuring data integrity with validation rules
Database Integration: Connecting Tkinter with SQLite
CRUD Operations: Implementing Create, Read, Update, and Delete functionality
Practice Exercise:
Create a Tkinter application for a simple library management system with the following features:
A form to add new books with fields: Title, Author, ISBN, and Quantity
Input validation for all fields
A list to display all books in the library
Functionality to update book details
Functionality to delete books from the library
Search functionality to find books by title or author
Use SQLite to store the library data and implement proper error handling throughout the application.