Building your own desktop productivity tools is one of the best ways to improve your Python skills. In this tutorial, we'll build FileSync PRO, a professional folder synchronization tool with a modern UI.
It allows you to:
🔄 Sync two folders instantly
⏱ Automatically sync every 30 seconds
📁 Mirror directories
📜 See real-time activity logs
🖥 Use a modern UI with ttkbootstrap
You can download the prebuilt release here:
👉 https://github.com/rogers-cyber/FileSyncPRO/releases/tag/v1.0.0
What We Are Building
Our final tool will include:
Source → Destination folder sync
Smart file modification detection
Background threading
Auto-sync loop
Activity logging
Modern dark UI
Project Structure
filesync-pro/
│
├── filesync_pro.py
├── logo.ico
└── error.log
Step 1 — Install Dependencies
We only need one external library.
pip install ttkbootstrap
ttkbootstrap gives modern themes for Tkinter apps.
Step 2 — Import Required Libraries
Now let's import the modules needed for our application.
import os
import sys
import shutil
import threading
import time
import traceback
from datetime import datetime
from queue import Queue, Empty
import tkinter as tk
from tkinter import filedialog, messagebox
import ttkbootstrap as tb
from ttkbootstrap.constants import *
What each module does
Module Purpose
os File system operations
shutil Copy files
threading Run sync in background
tkinter GUI framework
ttkbootstrap Modern UI styling
queue Thread-safe UI logging
Step 3 — Application Configuration
Define the app name and version.
APP_NAME = "FileSync PRO"
APP_VERSION = "1.0.0"
This allows us to reuse these values throughout the UI.
Step 4 — Create the Main Window
Now we create the main Tkinter window.
app = tk.Tk()
app.title(f"{APP_NAME} {APP_VERSION}")
app.geometry("1100x620")
tb.Style("darkly")
What this does
Creates the main app window
Sets window size
Applies the Darkly theme from ttkbootstrap
Step 5 — Create Global Variables
These variables will manage our app state.
ui_queue = Queue()
source_folder = tb.StringVar()
target_folder = tb.StringVar()
sync_running = False
auto_sync = False
Why we use StringVar
StringVar automatically updates UI widgets when values change.
Step 6 — Utility Functions
Next we create helper functions.
Resource Path
Useful when packaging the app into .exe.
def resource_path(file_name):
base = getattr(sys,"_MEIPASS",os.path.dirname(os.path.abspath(__file__)))
return os.path.join(base,file_name)
Error Logging
def log_error():
with open("error.log","a",encoding="utf-8") as f:
f.write(traceback.format_exc()+"\n")
This writes any errors to error.log.
UI Logger
def log(msg):
ui_queue.put(("log",msg))
Instead of writing directly to the UI from threads, we send messages through a queue.
Step 7 — Build the File Sync Engine
Now we create the core logic of the tool.
def sync_folders():
global sync_running
if not source_folder.get() or not target_folder.get():
messagebox.showerror("Error","Select source and target folders")
return
sync_running = True
src = source_folder.get()
dst = target_folder.get()
log("🔄 Synchronization started")
Validate user input
Before syncing, we check that both folders are selected.
Walk Through Files
for root, dirs, files in os.walk(src):
if not sync_running:
break
rel_path = os.path.relpath(root, src)
dst_path = os.path.join(dst, rel_path)
if not os.path.exists(dst_path):
os.makedirs(dst_path)
This recreates the folder structure in the destination.
Copy Updated Files
for file in files:
src_file = os.path.join(root,file)
dst_file = os.path.join(dst_path,file)
if not os.path.exists(dst_file) or \
os.path.getmtime(src_file) > os.path.getmtime(dst_file):
shutil.copy2(src_file,dst_file)
log(f"✔ Synced: {file}")
Here we only copy files if:
The file doesn't exist in destination
The source file is newer
This makes syncing fast and incremental.
Step 8 — Automatic Sync Loop
Now let's create an auto-sync feature.
def auto_sync_loop():
global auto_sync
auto_sync = True
log("⏱ Auto Sync started")
while auto_sync:
sync_folders()
for i in range(30):
if not auto_sync:
break
time.sleep(1)
log("🛑 Auto Sync stopped")
This runs the sync every 30 seconds.
Stop Auto Sync
def stop_auto_sync():
global auto_sync
auto_sync = False
Step 9 — Folder Selection
We allow users to browse folders.
Source Folder
def browse_source():
folder = filedialog.askdirectory()
if folder:
source_folder.set(folder)
Target Folder
def browse_target():
folder = filedialog.askdirectory()
if folder:
target_folder.set(folder)
Step 10 — Build the User Interface
App Title
title_frame = tb.Frame(app)
title_frame.pack(pady=(10,10))
tb.Label(
title_frame,
text=APP_NAME,
font=("Segoe UI",26,"bold"),
bootstyle="primary"
).pack()
Step 11 — Control Buttons
tb.Button(
frame_controls,
text="🔄 Start Sync",
bootstyle="success",
command=lambda: threading.Thread(target=sync_folders,daemon=True).start()
).pack(side="left",padx=5)
We use threads so the UI doesn't freeze.
Auto Sync Button
tb.Button(
frame_controls,
text="⏱ Start Auto Sync",
bootstyle="warning",
command=lambda: threading.Thread(target=auto_sync_loop,daemon=True).start()
).pack(side="left",padx=5)
Step 12 — Activity Log Panel
A logging console helps track operations.
log_text = tk.Text(log_frame)
log_text.pack(side="left",fill="both",expand=True)
scroll = tk.Scrollbar(log_frame,command=log_text.yview)
scroll.pack(side="right",fill="y")
Step 13 — Update UI From Background Threads
Because Tkinter is not thread-safe, we use a queue.
def process_ui_queue():
try:
while True:
cmd,data = ui_queue.get_nowait()
if cmd=="log":
log_text.config(state="normal")
log_text.insert("end",data+"\n")
log_text.see("end")
log_text.config(state="disabled")
except Empty:
pass
app.after(100,process_ui_queue)
This checks for updates every 100 ms.
Step 14 — Start the Application
Finally, we start the UI loop.
app.after(100,process_ui_queue)
app.mainloop()
Final Result
You now have a professional desktop file synchronization tool built with Python.
Features include:
🔄 One-click folder sync
📁 Directory mirroring
⚡ Incremental file updates
⏱ Automatic background syncing
📜 Real-time logs
🖥 Modern dark UI
Download the Ready-to-Use Version
If you want the compiled executable version:
👉 https://github.com/rogers-cyber/FileSyncPRO/releases/tag/v1.0.0
Ideas for Future Improvements
You can extend this project by adding:
File hashing verification
Drag & drop folders
Sync progress bar
File filters
Cloud sync
Multi-folder sync profiles


Top comments (0)