For small businesses, researchers, or hobbyists, managing data often requires a balance between simplicity, cost, and functionality. Microsoft Access is a popular choice, but it can be overkill for lightweight projects, requires licensing, and isn’t cross-platform. What if you could build a free, customizable data entry tool with just a few lines of code?

In this tutorial, we’ll create a user-friendly GUI application using Python, SQLite (a lightweight, file-based database), and Tkinter (Python’s built-in GUI library). This app will let you:

  • Enter new records (e.g., customer details) into a database.
  • Search and view records instantly.
  • Avoid the complexity of Access while retaining core functionality.

By the end, you’ll have a desktop app that runs on Windows, macOS, or Linux—no expensive software required. Let’s dive in!

Discover more

SQL

Application software

software

sqlite3

MS Access

application

GUI

py

Python

Graphical user interface

Table of Contents#

  1. Prerequisites
  2. Setting Up Your Project
  3. Creating the SQLite Database
  4. Designing the GUI with Tkinter
  5. Implementing Data Entry Functionality
  6. Adding Search Functionality
  7. Enhancing the GUI: Styling & Error Handling
  8. Testing the Application
  9. Conclusion & Next Steps
  10. References

Discover more

sqlite3

Software

gui

python

tkinter

Microsoft Access

databases

application

software

SQL

Prerequisites#

Before starting, ensure you have:

  • Python 3.6+: Download from python.org. Tkinter is included by default in most Python installations (check via python -m tkinter in the terminal).
  • Basic Python Knowledge: Familiarity with variables, functions, and loops will help, but we’ll explain key concepts step-by-step.
  • SQLite: No separate installation needed—Python’s built-in sqlite3 library handles everything.

Setting Up Your Project#

Let’s organize our project for clarity. Create a new folder (e.g., sqlite_gui_app) and add a blank file named main.py—this will be our main script.

Your project structure will look like this:

sqlite_gui_app/  
└── main.py  

We’ll use Python’s built-in libraries, so no need for pip install—just open main.py in your code editor (e.g., VS Code, PyCharm, or even Notepad++).

Creating the SQLite Database#

SQLite databases are stored as single files (e.g., mydatabase.db), making them easy to share or back up. We’ll write code to:

  1. Connect to a database (or create it if it doesn’t exist).
  2. Create a customers table to store sample data (name, email, phone, address).

Step 1: Initialize the Database#

Add this code to main.py to set up the database and table:

import sqlite3  from tkinter import messagebox   def init_db():      """Initialize the database and create the customers table if it doesn't exist."""      try:          # Connect to the database (creates it if it doesn't exist)          conn = sqlite3.connect('mydatabase.db')          cursor = conn.cursor()           # Create customers table with id (auto-increment), name, email, phone, address          cursor.execute('''              CREATE TABLE IF NOT EXISTS customers (                  id INTEGER PRIMARY KEY AUTOINCREMENT,                  name TEXT NOT NULL,                  email TEXT NOT NULL UNIQUE,  # Prevent duplicate emails                  phone TEXT,                  address TEXT              )          ''')           conn.commit()          conn.close()          messagebox.showinfo("Success", "Database initialized successfully!")      except sqlite3.Error as e:          messagebox.showerror("Database Error", f"Error initializing database: {e}")   # Call init_db() when the app starts to ensure the table exists  init_db()  

What this does:

  • sqlite3.connect('mydatabase.db') creates mydatabase.db in your project folder if it doesn’t exist.
  • CREATE TABLE IF NOT EXISTS ensures we don’t overwrite existing tables.
  • UNIQUE on email prevents duplicate entries (handy for data integrity).

Designing the GUI with Tkinter#

Tkinter is Python’s standard GUI library—no extra installation required. We’ll build a window with:

  • Input fields for data entry (name, email, phone, address).
  • Buttons to "Add Record" and "Search".
  • A table (Treeview) to display search results.

Step 1: Import Tkinter and Set Up the Main Window#

Add this code below the init_db function to create the GUI skeleton:

import tkinter as tk  from tkinter import ttk   # Create the main window  root = tk.Tk()  root.title("Python SQLite GUI - Data Entry & Search")  root.geometry("800x600")  # Window size: width x height  root.resizable(True, True)  # Allow resizing   # Configure grid layout for responsiveness  root.grid_columnconfigure(0, weight=1)  root.grid_rowconfigure(0, weight=1)  

Step 2: Add Input Fields and Buttons#

We’ll use ttk (themed Tkinter) for modern, consistent widgets. Add this code to create labels, entry boxes, and buttons:

# Frame for data entry (top section)  entry_frame = ttk.LabelFrame(root, text="Enter New Record", padding="10")  entry_frame.grid(row=0, column=0, padx=10, pady=10, sticky="nsew")   # Labels and Entry Widgets  labels = ["Name:", "Email:", "Phone:", "Address:"]  entries = {}  # To store entry widgets for later access   for i, label_text in enumerate(labels):      # Label      ttk.Label(entry_frame, text=label_text).grid(row=i, column=0, padx=5, pady=5, sticky="w")      # Entry (input) widget      entry = ttk.Entry(entry_frame, width=50)      entry.grid(row=i, column=1, padx=5, pady=5, sticky="ew")      entries[label_text[:-1].lower()] = entry  # Store entries with keys: "name", "email", etc.   # Configure entry_frame columns to expand  entry_frame.grid_columnconfigure(1, weight=1)   # Frame for buttons (below entry fields)  button_frame = ttk.Frame(root)  button_frame.grid(row=1, column=0, padx=10, pady=5, sticky="ew")   # Buttons  add_btn = ttk.Button(button_frame, text="Add Record", command=lambda: add_record())  add_btn.pack(side="left", padx=5)   search_btn = ttk.Button(button_frame, text="Search", command=lambda: search_records())  search_btn.pack(side="left", padx=5)   clear_btn = ttk.Button(button_frame, text="Clear Fields", command=lambda: clear_fields())  clear_btn.pack(side="left", padx=5)  

What this does:

  • ttk.LabelFrame groups input fields for clarity.
  • entries dictionary stores input widgets so we can access their values later.
  • Buttons are packed in a horizontal frame for neatness.

Step 3: Add a Treeview for Search Results#

ttk.Treeview widget displays search results in a table. Add this code to create the results table:

# Frame for search results (bottom section)  results_frame = ttk.LabelFrame(root, text="Search Results", padding="10")  results_frame.grid(row=2, column=0, padx=10, pady=10, sticky="nsew")   # Configure results_frame to expand with window  root.grid_rowconfigure(2, weight=1)   # Create Treeview (table) for results  columns = ("ID", "Name", "Email", "Phone", "Address")  tree = ttk.Treeview(results_frame, columns=columns, show="headings", height=10)   # Set column headings and widths  for col in columns:      tree.heading(col, text=col)      tree.column(col, width=100 if col == "ID" else 150)  # Narrower ID column   # Add scrollbar for Treeview  scrollbar = ttk.Scrollbar(results_frame, orient="vertical", command=tree.yview)  tree.configure(yscroll=scrollbar.set)   # Grid Treeview and scrollbar  tree.grid(row=0, column=0, sticky="nsew")  scrollbar.grid(row=0, column=1, sticky="ns")   # Configure results_frame grid  results_frame.grid_columnconfigure(0, weight=1)  results_frame.grid_rowconfigure(0, weight=1)  

What this does:

  • Treeview with columns matching our customers table.
  • show="headings" hides the default first column (we use "ID" instead).
  • Scrollbar lets users navigate long result lists.

Implementing Data Entry Functionality#

Now, let’s make the "Add Record" button work. We’ll write a function to:

  1. Get input from the entry fields.
  2. Validate inputs (e.g., ensure name/email aren’t empty).
  3. Insert the record into the SQLite database.

Step 1: Write the add_record Function#

Add this code below the GUI setup:

def add_record():      """Add a new record to the customers table."""      # Get input values from entry widgets      name = entries["name"].get().strip()      email = entries["email"].get().strip()      phone = entries["phone"].get().strip()      address = entries["address"].get().strip()       # Validate required fields      if not name or not email:          messagebox.showwarning("Input Error", "Name and Email are required!")          return       try:          # Connect to the database          conn = sqlite3.connect('mydatabase.db')          cursor = conn.cursor()           # Insert new record (parameterized query to prevent SQL injection)          cursor.execute('''              INSERT INTO customers (name, email, phone, address)              VALUES (?, ?, ?, ?)          ''', (name, email, phone, address))           conn.commit()          conn.close()          messagebox.showinfo("Success", "Record added successfully!")          clear_fields()  # Clear input fields after adding      except sqlite3.IntegrityError:          messagebox.showerror("Duplicate Error", "Email already exists! Use a unique email.")      except sqlite3.Error as e:          messagebox.showerror("Database Error", f"Error adding record: {e}")  

Step 2: Add a clear_fields Function#

To reset input fields after adding a record, add:

def clear_fields():      """Clear all input fields."""      for entry in entries.values():          entry.delete(0, tk.END)  

Adding Search Functionality#

The "Search" button will let users query the database by name, email, or phone. We’ll add a search bar and dropdown to select the search criteria.

Step 1: Add Search Inputs#

Insert this code between the button_frame and results_frame sections to add search controls:

# Frame for search (between buttons and results)  search_frame = ttk.LabelFrame(root, text="Search Records", padding="10")  search_frame.grid(row=1, column=0, padx=10, pady=5, sticky="ew")   # Search criteria dropdown and entry  ttk.Label(search_frame, text="Search by:").pack(side="left", padx=5)  search_by = tk.StringVar(value="name")  # Default to searching by name  search_dropdown = ttk.Combobox(search_frame, textvariable=search_by, values=["name", "email", "phone"], state="readonly", width=10)  search_dropdown.pack(side="left", padx=5)   ttk.Label(search_frame, text="Search term:").pack(side="left", padx=5)  search_entry = ttk.Entry(search_frame, width=30)  search_entry.pack(side="left", padx=5, fill="x", expand=True)  

Step 2: Write the search_records Function#

This function queries the database based on the selected criteria (name, email, or phone) and displays results in the Treeview:

def search_records():      """Search the database and display results in the Treeview."""      # Get search criteria and term      criteria = search_by.get()      term = search_entry.get().strip()       if not term:          messagebox.showwarning("Input Error", "Enter a search term!")          return       try:          # Connect to the database          conn = sqlite3.connect('mydatabase.db')          cursor = conn.cursor()           # Query based on selected criteria (use LIKE for partial matches)          if criteria == "name":              cursor.execute("SELECT * FROM customers WHERE name LIKE ?", (f"%{term}%",))          elif criteria == "email":              cursor.execute("SELECT * FROM customers WHERE email LIKE ?", (f"%{term}%",))          elif criteria == "phone":              cursor.execute("SELECT * FROM customers WHERE phone LIKE ?", (f"%{term}%",))           # Fetch all results          results = cursor.fetchall()          conn.close()           # Clear previous results in Treeview          for item in tree.get_children():              tree.delete(item)           # Insert new results into Treeview          if results:              for row in results:                  tree.insert("", tk.END, values=row)          else:              messagebox.showinfo("No Results", "No records found matching your search.")       except sqlite3.Error as e:          messagebox.showerror("Database Error", f"Error searching records: {e}")  

What this does:

  • LIKE ? with %term% allows partial matches (e.g., searching "john" finds "Johnny").
  • tree.delete(item) clears old results before showing new ones.

Enhancing the GUI: Styling & Error Handling#

Let’s polish the app with better styling and user feedback.

Step 1: Add Custom Styling#

Tkinter’s ttk.Style lets you customize colors and fonts. Add this code after creating the main window (root = tk.Tk()):

# Custom styling  style = ttk.Style()  style.configure("TLabelFrame", background="#f0f0f0")  # Light gray background for frames  style.configure("TButton", font=("Helvetica", 10, "bold"))  # Bold buttons  style.configure("Treeview.Heading", background="#4CAF50", foreground="white")  # Green headers  root.configure(bg="#f0f0f0")  # Match main window background to frames  

Step 2: Run the Main GUI Loop#

Add this line at the end of main.py to start the GUI:

# Start the main event loop  root.mainloop()  

Testing the Application#

Now, run the app by executing main.py in your terminal:

python main.py  

Test these features:

  1. Add a Record: Fill in name, email, and optional fields, then click "Add Record". You’ll see a success message.
  2. Duplicate Email: Try adding a record with an existing email—you’ll get an error.
  3. Search: Enter a name/email/phone and select the criteria, then click "Search". Results appear in the table.

Discover more

py

software

Application

Python

Tkinter

MS Access

db

SQLite

application

Database

Conclusion#

You’ve built a fully functional data entry and search tool with Python, SQLite, and Tkinter! This app is:

  • Free: No licensing fees (unlike MS Access).
  • Lightweight: Runs on any OS (Windows, macOS, Linux) with Python installed.
  • Customizable: Extend it by adding "Edit/Delete" buttons, exporting to CSV, or adding more fields (e.g., date of birth).

Discover more

application

SQL

py

sqlite

SQLite

app

python

Application

Microsoft Access

GUI

References#

Happy coding! 🐍📊

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐