DEV Community

Mate Technologies
Mate Technologies

Posted on

QuickSort PRO – Step-by-Step Tutorial (File Size Organizer in Python)

QuickSort PRO is a professional file size organizer that lets you sort files by size, move/copy them, and track progress—all with a simple GUI. This tutorial breaks it down for beginners.

1️⃣ Prerequisites

Before starting, make sure you have:

Python 3.10+

The following packages installed:

pip install ttkbootstrap tkinterdnd2
Enter fullscreen mode Exit fullscreen mode

You also need a code editor like VS Code or PyCharm.

You can download the source or Windows executable:

GitHub Repository: https://github.com/rogers-cyber/QuickSort.git

Windows EXE Download: GitHub Releases

2️⃣ Setting Up the App

We start by importing all required modules and creating the main Tkinter window.

import os
import sys
import shutil
import threading
import time
import traceback
from queue import Queue, Empty
from tkinter import filedialog, messagebox
import tkinter as tk

import ttkbootstrap as tb
from ttkbootstrap.constants import *
from tkinterdnd2 import DND_FILES, TkinterDnD

# App configuration
APP_NAME = "QuickSort - File Size Organizer"
APP_VERSION = "1.0.0"

app = TkinterDnD.Tk()
app.title(f"{APP_NAME} {APP_VERSION}")
app.geometry("1120x650")

tb.Style("darkly")  # Dark theme
Enter fullscreen mode Exit fullscreen mode

Explanation:

ttkbootstrap is used for modern themed widgets.

TkinterDnD allows drag & drop for files.

Queue helps safely update UI from threads.

3️⃣ Utility Functions

These functions handle resources, errors, and the About dialog.

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)

def log_error():
    with open("error.log", "a", encoding="utf-8") as f:
        f.write(traceback.format_exc() + "\n")

def show_about():
    messagebox.showinfo(
        f"About {APP_NAME}",
        f"{APP_NAME} v{APP_VERSION}\nProfessional File Size Organizer\n"
        "Features:\n"
        "• Drag & Drop files or folders\n"
        "• Sort files by size\n"
        "• Move or Copy files\n"
        "• Live progress tracking\n"
        "• Detailed logging\n"
        "Built with Python + Tkinter + ttkbootstrap"
    )
Enter fullscreen mode Exit fullscreen mode

Explanation:

resource_path() ensures resources (like icons) work even after packaging with PyInstaller.

log_error() logs exceptions.

show_about() opens a simple “About” window.

4️⃣ Adding a Menu

menubar = tb.Menu(app)
help_menu = tb.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)
Enter fullscreen mode Exit fullscreen mode

Explanation:

A menu bar is added with a Help → About option.

5️⃣ File List and Output Folder

We need to store files and the target folder:

file_list = []
output_path = tb.StringVar()
operation_mode = tb.StringVar(value="Move")
ui_queue = Queue()
Enter fullscreen mode Exit fullscreen mode

Explanation:

file_list stores all files added by the user.

output_path stores the selected destination folder.

operation_mode allows Move or Copy operations.

ui_queue updates the UI safely from threads.

6️⃣ File Selection Frame

This frame lets the user add files/folders, clear the list, and choose output folder:

frame1 = tb.Labelframe(app, text="Files & Folders", padding=10)
frame1.pack(fill="x", padx=10, pady=6)

file_listbox = tk.Listbox(frame1, height=7, selectmode="extended")
file_listbox.pack(side="left", fill="x", expand=True)

scroll = tb.Scrollbar(frame1, command=file_listbox.yview)
scroll.pack(side="right", fill="y")
file_listbox.config(yscrollcommand=scroll.set)
Enter fullscreen mode Exit fullscreen mode

Explanation:

Listbox displays selected files.

Scrollbar is linked to Listbox for easy navigation.

7️⃣ File Operations Functions

def add_files():
    files = filedialog.askopenfilenames(title="Select Files")
    for f in files:
        if f not in file_list:
            file_list.append(f)
            ui_queue.put(("add", f))

def add_folder():
    folder = filedialog.askdirectory(title="Select Folder")
    if not folder:
        return
    for root, dirs, files in os.walk(folder):
        for name in files:
            path = os.path.join(root, name)
            if path not in file_list:
                file_list.append(path)
                ui_queue.put(("add", path))

def clear_list():
    file_list.clear()
    ui_queue.put(("clear", None))

def set_output_folder():
    folder = filedialog.askdirectory()
    if folder:
        output_path.set(folder)
Enter fullscreen mode Exit fullscreen mode

Explanation:

Users can add individual files, entire folders, or clear the list.

ui_queue.put() ensures the Listbox updates safely from the main thread.

8️⃣ Size Categorization

Files are organized into size ranges:

def size_category(size):
    if size < 1 * 1024 * 1024:
        return "0-1MB"
    elif size < 10 * 1024 * 1024:
        return "1-10MB"
    elif size < 100 * 1024 * 1024:
        return "10-100MB"
    elif size < 1024 * 1024 * 1024:
        return "100MB-1GB"
    else:
        return "1GB+"
Enter fullscreen mode Exit fullscreen mode

Explanation:

The function returns a human-readable category for the file size.

9️⃣ Organize Files Function

This function handles the main file moving/copying logic:

def organize_files():
    global stop_flag, pause_flag
    stop_flag = False
    pause_flag = False

    total = len(file_list)
    if total == 0:
        messagebox.showerror("Error", "No files selected.")
        return

    out_dir = output_path.get() or os.path.dirname(file_list[0])

    for idx, file in enumerate(file_list, 1):
        if stop_flag: break
        while pause_flag: time.sleep(0.2)
        try:
            size = os.path.getsize(file)
            folder = size_category(size)
            dest_dir = os.path.join(out_dir, folder)
            os.makedirs(dest_dir, exist_ok=True)
            dest = os.path.join(dest_dir, os.path.basename(file))
            if operation_mode.get() == "Move":
                shutil.move(file, dest)
            else:
                shutil.copy2(file, dest)
            ui_queue.put(("log", f"{os.path.basename(file)} -> {folder}"))
        except Exception:
            log_error()
            ui_queue.put(("log", f"❌ Failed: {file}"))
Enter fullscreen mode Exit fullscreen mode

Explanation:

Checks for stop/pause flags.

Creates folders by size category.

Moves or copies files depending on the user selection.

Updates the log for each file.

1️⃣0️⃣ Drag & Drop Support

def drop(event):
    files = app.tk.splitlist(event.data)
    for f in files:
        if os.path.isfile(f):
            if f not in file_list:
                file_list.append(f)
                ui_queue.put(("add", f))
        elif os.path.isdir(f):
            for root, dirs, names in os.walk(f):
                for name in names:
                    path = os.path.join(root, name)
                    if path not in file_list:
                        file_list.append(path)
                        ui_queue.put(("add", path))

file_listbox.drop_target_register(DND_FILES)
file_listbox.dnd_bind("<<Drop>>", drop)
Enter fullscreen mode Exit fullscreen mode

Explanation:

Users can drag & drop files or folders directly onto the Listbox.

1️⃣1️⃣ Running the App

Finally, start the UI loop:

app.after(100, process_ui_queue)
app.mainloop()
Enter fullscreen mode Exit fullscreen mode

Explanation:

process_ui_queue() updates the UI every 100ms.

mainloop() runs the Tkinter app.

✅ That’s it! You now have a fully functional QuickSort PRO file organizer with GUI, drag & drop support, and size-based sorting.

For full source code and Windows installer:

GitHub: https://github.com/rogers-cyber/QuickSort.git

Windows EXE: Download here

Top comments (0)