🔍 Build a Desktop File Content Search App with Python & Tkinter

Published: (February 19, 2026 at 12:10 AM EST)
5 min read
Source: Dev.to

Source: Dev.to

File Search System Tutorial

Searching filenames is easy — searching inside files is where things get interesting.

In this tutorial we’ll build a desktop File Search System using Python, Tkinter, and ttkbootstrap that can:

  • Recursively scan folders
  • Search inside files (TXT, CSV, XLSX, PDF, XML)
  • Support regex searches
  • Show live progress, speed & ETA
  • Preview matched content
  • Export results to CSV

📦 Download / Clone
👉


🧰 Step 1: Install Required Libraries

Make sure you have Python 3.9+ installed, then run:

pip install ttkbootstrap xlrd PyPDF2

📁 Step 2: Import Required Modules

We’ll import modules for file handling, regex searching, threading, GUI, and file parsing.

import os
import sys
import re
import fnmatch
import threading
import time
import xlrd
import PyPDF2
import xml.etree.ElementTree as ET
import tkinter as tk
from tkinter import filedialog, messagebox
import ttkbootstrap as tb
from ttkbootstrap.constants import *

⚙️ Step 3: App Configuration

Define your app name and version in one place.

APP_NAME = "File Search System"
APP_VERSION = "1.0.1"

🪟 Step 4: Initialize the Application Window

Create the main Tkinter window and apply a modern theme.

app = tk.Tk()
style = tb.Style(theme="superhero")
app.title(f"{APP_NAME} {APP_VERSION}")
app.geometry("1230x680")

🖼 Step 5: Handle App Resources (Icons)

This ensures compatibility with PyInstaller builds.

def resource_path(file_name):
    base_path = getattr(sys, "_MEIPASS", os.path.dirname(os.path.abspath(__file__)))
    return os.path.join(base_path, file_name)

ℹ️ Step 6: Create an “About” Dialog

Adds a professional touch to your app.

def show_about():
    messagebox.showinfo(
        f"About {APP_NAME} v{APP_VERSION}",
        f"{APP_NAME} v{APP_VERSION}\n"
        "Production Edition\n\n"
        "A desktop utility for searching inside files.\n\n"
        "✔ Regex search\n"
        "✔ Multi-file support\n"
        "✔ Live progress & previews\n\n"
        "© 2026 Mate Technologies"
    )

📋 Step 7: Add a Menu Bar

Attach the About dialog to a Help menu.

menubar = tk.Menu(app)
help_menu = tk.Menu(menubar, tearoff=0)
help_menu.add_command(label="About", command=show_about)
menubar.add_cascade(label="Help", menu=help_menu)
app.config(menu=menubar)

📂 Step 8: Build the Search Settings UI

Lets users choose a folder and a search term.

frame1 = tb.Labelframe(app, text="Search Settings", padding=10)
frame1.pack(fill="x", padx=10, pady=6)

root_path   = tk.StringVar()
search_var  = tk.StringVar()
regex_var   = tk.BooleanVar()

tb.Label(frame1, text="Root Folder:").pack(side="left")
tb.Entry(frame1, textvariable=root_path, width=50).pack(side="left")
tb.Button(
    frame1,
    text="Browse",
    command=lambda: root_path.set(filedialog.askdirectory())
).pack(side="left")

🧹 Step 9: Add File Filters & Controls

Users can limit file types and exclude folders.

file_filter     = tk.StringVar(value="*")
exclude_folders = tk.StringVar(value="node_modules .git __pycache__")

search_btn = tb.Button(frame1, text="🔍 SEARCH", bootstyle="success")
stop_btn   = tb.Button(frame1, text="🛑 STOP", bootstyle="danger-outline", state="disabled")

📊 Step 10: Progress Bar & Live Stats

Track progress, speed, ETA, and matches.

progress_var = tk.IntVar()
tb.Progressbar(app, variable=progress_var, maximum=100).pack(fill="x")

eta_lbl      = tb.Label(app, text="ETA: --")
spd_lbl      = tb.Label(app, text="Speed: -- files/s")
counter_lbl  = tb.Label(app, text="Matches: 0")

📄 Step 11: Display Search Results

A Treeview shows file paths and preview text.

tree = tb.Treeview(app, columns=("path", "preview"), show="headings")
tree.heading("path",    text="File Path")
tree.heading("preview", text="Match Preview")
tree.pack(fill="both", expand=True)

🧠 Step 12: Search Logic Helpers

File filtering

def allowed_file(name):
    pats = file_filter.get().lower().split()
    return "*" in pats or any(fnmatch.fnmatch(name, p) for p in pats)

Folder exclusion

def excluded_dir(path):
    return any(ex in path.lower() for ex in exclude_folders.get().split())

🔍 Step 13: Read File Contents with Preview

Handles TXT, CSV, XLSX, PDF, and XML (the full version on GitHub supports all formats).

def read_file_content_with_preview(path, query, use_regex=False):
    if path.endswith(".txt"):
        with open(path, "r", errors="ignore") as f:
            for i, line in enumerate(f, 1):
                if re.search(query, line, re.I):
                    return True, f"Line {i}: {line[:100]}"
    # (Other formats omitted for brevity)
    return False, ""

🚀 Step 14: Run the Search in a Thread

Keeps the UI responsive.

def run_search():
    for root, dirs, files in os.walk(root_path.get()):
        # Skip excluded directories
        dirs[:] = [d for d in dirs if not excluded_dir(os.path.join(root, d))]
        for file in files:
            if allowed_file(file):
                path = os.path.join(root, file)
                found, preview = read_file_content_with_preview(
                    path, search_var.get(), regex_var.get()
                )
                # Update UI (progress bar, treeview, counters) here...

You would typically start this function in a separate thread:

search_thread = threading.Thread(target=run_search, daemon=True)
search_thread.start()

🎉 That’s it!

You now have a functional desktop File Search System that can:

  • Scan directories recursively
  • Search inside multiple file types (TXT, CSV, XLSX, PDF, XML)
  • Use plain‑text or regex queries
  • Show live progress, speed, ETA, and match previews
  • Export results to CSV (implementation left as an exercise)

Feel free to explore the full source code on GitHub for additional features such as PDF/XML parsing, CSV/XLSX handling, and result exporting. Happy searching!

Step 15: Export Results to CSV

def export_results():
    file = filedialog.asksaveasfilename(defaultextension=".csv")
    with open(file, "w", encoding="utf-8") as f:
        for row in results_list:
            f.write(",".join(row) + "\n")

Step 16: Start the App

app.mainloop()

✅ Final Result

You now have a fully functional desktop file‑content search tool with:

  • Clean UI
  • Threaded scanning
  • Multiple file‑format support
  • Live progress & previews
  • CSV export

📦 Download / Clone from GitHub

👉

File Search System Screenshot

0 views
Back to Blog

Related posts

Read more »