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
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
๐ผ๏ธ 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)
โ๏ธ 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()
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
We store:
Search folder
Search mode
Query text
A cancel flag
3.3 Allow Canceling the Search
def stop(self):
self._running = False
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)
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))
File Name & Content Search
for f in files:
path = os.path.join(root, f)
File name search:
if self.search_type == "File Name":
if self.query in f.lower():
self.found.emit(path)
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)
Progress Updates
percent = int((processed_folders / total_folders) * 100)
self.progress.emit(percent)
๐ฅ๏ธ Step 4 โ Main Application Window
class FinderApp(QWidget):
def __init__(self):
super().__init__()
We configure the window:
self.setWindowIcon(QIcon(resource_path("logo.ico")))
self.setWindowTitle("FileScope - Professional Finder Tool")
self.setMinimumSize(950, 550)
๐๏ธ Step 5 โ Building the User Interface
5.1 Title
title = QLabel("๐ FileScope")
title.setAlignment(Qt.AlignCenter)
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)
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)
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)
๐ 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)
Smooth Animation Timer
self.timer = QTimer()
self.timer.timeout.connect(self.update_progress_smooth)
self.timer.start(15)
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
);
}
""")
This creates the animated glowing bar.
๐ Step 7 โ Showing Results
self.results_list = QListWidget()
self.results_list.itemDoubleClicked.connect(self.open_item)
Double-clicking opens the file or folder automatically.
๐งฎ Step 8 โ Live Match Counter
self.match_counter_label = QLabel("Matches found: 0")
Updated every time a result is found.
๐ Step 9 โ Starting the Search
self.worker = SearchWorker(
self.root_path,
self.search_type.currentText(),
query
)
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()
โ Step 10 โ Canceling the Search
def cancel_search(self):
if self.worker:
self.worker.stop()
๐ 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;
}
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())
โ 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

Top comments (0)