DEV Community

Mate Technologies
Mate Technologies

Posted on

๐Ÿ” Building FileScope โ€“ A Professional File Finder in Python (Step-by-Step)

FileScope is a desktop tool built with Python + PySide6 that lets you:

Search folders by name

Search files by name

Search for words inside files

See a smooth glowing animated progress bar

Cancel searches anytime

๐Ÿ‘‰ Download the free compiled EXE (Windows):
https://matetools.gumroad.com/l/bwlhs

๐Ÿงฐ Step 0 โ€“ What Youโ€™ll Need

Before starting, install PySide6:

pip install PySide6

Now letโ€™s build the app piece by piece.

๐Ÿ“ Step 1 โ€“ Imports and App Metadata

We start by importing standard Python modules and PySide6 UI components.

import os
import sys
import subprocess
import platform
Enter fullscreen mode Exit fullscreen mode

Now the PySide6 widgets, core tools, and icons:

from PySide6.QtWidgets import (
    QApplication, QWidget, QFileDialog, QVBoxLayout, QHBoxLayout,
    QPushButton, QLabel, QLineEdit, QListWidget, QComboBox, QProgressBar,
    QMessageBox
)
from PySide6.QtCore import Qt, QThread, Signal, QTimer
from PySide6.QtGui import QIcon
Enter fullscreen mode Exit fullscreen mode

๐Ÿ–ผ๏ธ Step 2 โ€“ Loading Resources Correctly (EXE-Friendly)

When packaging with PyInstaller, file paths change.
This helper ensures icons work in both script and EXE mode.

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)
Enter fullscreen mode Exit fullscreen mode

โš™๏ธ Step 3 โ€“ Creating a Worker Thread (Non-Blocking Search)

File searching can take time, so we use QThread to keep the UI responsive.

3.1 Define the Worker

class SearchWorker(QThread):
    found = Signal(str)
    progress = Signal(int)
    finished = Signal()
Enter fullscreen mode Exit fullscreen mode

These signals send updates back to the UI safely.

3.2 Initialize the Worker

def __init__(self, root_path, search_type, query):
    super().__init__()
    self.root_path = root_path
    self.search_type = search_type
    self.query = query.lower()
    self._running = True
Enter fullscreen mode Exit fullscreen mode

We store:

Search folder

Search mode

Query text

A cancel flag

3.3 Allow Canceling the Search

def stop(self):
    self._running = False
Enter fullscreen mode Exit fullscreen mode

3.4 The Search Logic

def run(self):
    total_folders = sum(len(dirs) for _, dirs, _ in os.walk(self.root_path))
    total_folders = max(total_folders, 1)
Enter fullscreen mode Exit fullscreen mode

We estimate progress based on folders scanned.

Folder Name Search

if self.search_type == "Folder Name":
    for d in dirs:
        if self.query in d.lower():
            self.found.emit(os.path.join(root, d))
Enter fullscreen mode Exit fullscreen mode

File Name & Content Search

for f in files:
    path = os.path.join(root, f)
Enter fullscreen mode Exit fullscreen mode

File name search:

if self.search_type == "File Name":
    if self.query in f.lower():
        self.found.emit(path)
Enter fullscreen mode Exit fullscreen mode

Word inside file search:

elif self.search_type == "Word in File":
    with open(path, "r", encoding="utf-8", errors="ignore") as file:
        if self.query in file.read().lower():
            self.found.emit(path)
Enter fullscreen mode Exit fullscreen mode

Progress Updates

percent = int((processed_folders / total_folders) * 100)
self.progress.emit(percent)
Enter fullscreen mode Exit fullscreen mode

๐Ÿ–ฅ๏ธ Step 4 โ€“ Main Application Window

class FinderApp(QWidget):
    def __init__(self):
        super().__init__()
Enter fullscreen mode Exit fullscreen mode

We configure the window:

self.setWindowIcon(QIcon(resource_path("logo.ico")))
self.setWindowTitle("FileScope - Professional Finder Tool")
self.setMinimumSize(950, 550)
Enter fullscreen mode Exit fullscreen mode

๐ŸŽ›๏ธ Step 5 โ€“ Building the User Interface
5.1 Title

title = QLabel("๐Ÿ“ FileScope")
title.setAlignment(Qt.AlignCenter)
Enter fullscreen mode Exit fullscreen mode

5.2 Folder Selection Controls

self.path_input = QLineEdit()
self.path_input.setReadOnly(True)

browse_btn = QPushButton("Browse")
browse_btn.clicked.connect(self.browse_folder)
Enter fullscreen mode Exit fullscreen mode

5.3 Search Options

self.search_type = QComboBox()
self.search_type.addItems(["Folder Name", "File Name", "Word in File"])

self.query_input = QLineEdit()
self.query_input.setPlaceholderText("Enter search text")
self.query_input.returnPressed.connect(self.start_search)
Enter fullscreen mode Exit fullscreen mode

5.4 Action Buttons

self.search_btn = QPushButton("Search")
self.search_btn.clicked.connect(self.start_search)

self.cancel_btn = QPushButton("Cancel")
self.cancel_btn.setEnabled(False)
self.cancel_btn.clicked.connect(self.cancel_search)
Enter fullscreen mode Exit fullscreen mode

๐ŸŒˆ Step 6 โ€“ Hybrid Glowing Progress Bar

We start with an indeterminate spinner, then switch to real progress.

self.progress_bar = QProgressBar()
self.progress_bar.setMaximum(100)
self.progress_bar.setValue(0)
self.progress_bar.setTextVisible(False)
Enter fullscreen mode Exit fullscreen mode

Smooth Animation Timer

self.timer = QTimer()
self.timer.timeout.connect(self.update_progress_smooth)
self.timer.start(15)
Enter fullscreen mode Exit fullscreen mode

Glow Effect Logic

self.glow_pos = (self.glow_pos + 1) % 200

self.progress_bar.setStyleSheet("""
QProgressBar::chunk {
    background: qlineargradient(
        x1:0, y1:0, x2:1, y2:0,
        stop:0 #2563eb, stop:0.5 #60a5fa, stop:1 #2563eb
    );
}
""")
Enter fullscreen mode Exit fullscreen mode

This creates the animated glowing bar.

๐Ÿ“‹ Step 7 โ€“ Showing Results

self.results_list = QListWidget()
self.results_list.itemDoubleClicked.connect(self.open_item)
Enter fullscreen mode Exit fullscreen mode

Double-clicking opens the file or folder automatically.

๐Ÿงฎ Step 8 โ€“ Live Match Counter

self.match_counter_label = QLabel("Matches found: 0")
Enter fullscreen mode Exit fullscreen mode

Updated every time a result is found.

๐Ÿš€ Step 9 โ€“ Starting the Search

self.worker = SearchWorker(
    self.root_path,
    self.search_type.currentText(),
    query
)
Enter fullscreen mode Exit fullscreen mode

Signals are connected:

self.worker.found.connect(self.add_result)
self.worker.progress.connect(self.set_target_progress)
self.worker.finished.connect(self.search_finished)
self.worker.start()
Enter fullscreen mode Exit fullscreen mode

โŒ Step 10 โ€“ Canceling the Search

def cancel_search(self):
    if self.worker:
        self.worker.stop()
Enter fullscreen mode Exit fullscreen mode

๐Ÿ“‚ Step 11 โ€“ Opening Files Cross-Platform

if platform.system() == "Windows":
    os.startfile(path)
elif platform.system() == "Darwin":
    subprocess.Popen(["open", path])
else:
    subprocess.Popen(["xdg-open", path])

๐ŸŽจ Step 12 โ€“ Dark Professional Styling
QWidget {
    background-color: #0f172a;
    color: #e5e7eb;
}
Enter fullscreen mode Exit fullscreen mode

Modern business-grade dark UI.

โ–ถ๏ธ Step 13 โ€“ Launching the App

if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = FinderApp()
    window.show()
    sys.exit(app.exec())
Enter fullscreen mode Exit fullscreen mode

โœ… Final Result

You now have:

โœ” Multi-threaded file search
โœ” Smooth glowing progress bar
โœ” Cancelable operations
โœ” Cross-platform file opening
โœ” Professional UI
โœ” EXE-ready structure

๐Ÿ“ฆ Free Download (No Setup Required)

๐Ÿ‘‰ Windows EXE:
https://matetools.gumroad.com/l/bwlhs

FileScope โ€“ Professional File & Folder Finder Tool

Top comments (0)