Renaming lots of files manually is tedious. In this tutorial, weβll build a desktop GUI app in Python using Tkinter that lets users:
Select a folder
Preview file renaming changes
Add prefixes/suffixes
Find & replace text in filenames
Rename files safely
Undo the last rename operation
No prior Tkinter experience required π
π§° Step 1: Import the Required Modules
Letβs start by importing everything we need.
import tkinter as tk
from tkinter import filedialog, messagebox
import os
from copy import deepcopy
Why these imports?
tkinter β builds the GUI
filedialog β opens a folder picker
messagebox β shows popups (errors, confirmations)
os β works with files and paths
deepcopy β safely store original filenames for undo
ποΈ Step 2: Create the Main Application Class
Weβll wrap the entire app inside a class to keep things organized.
class FileRenamerApp:
def __init__(self, root):
self.root = root
self.root.title("File Renamer")
self.root.geometry("700x700")
self.root.configure(bg="#1f2f3a")
self.root.resizable(False, False)
Whatβs happening here?
root is the main Tkinter window
We set:
window title
fixed size
background color
disable resizing
π§ Step 3: Store App State (Important!)
Weβll keep track of files and renaming history.
self.folder_path = ""
self.files = []
self.original_files = []
self.preview_files = []
Why do we need this?
files β current files in the folder
original_files β used for undo
preview_files β shows renamed filenames before applying
π¨ Step 4: Build the User Interface Skeleton
At the end of init, we call a method that builds the UI.
self.create_ui()
Letβs define that next.
πΌοΈ Step 5: App Title
def create_ui(self):
tk.Label(
self.root,
text="File Renamer",
font=("Helvetica", 28, "bold"),
bg="#1f2f3a",
fg="#ffffff"
).pack(pady=20)
This adds a big title at the top of the window.
π Step 6: Folder Selection Section
Folder input + Browse button
folder_frame = tk.Frame(self.root, bg="#1f2f3a")
folder_frame.pack(pady=10, fill="x", padx=20)
tk.Label(
folder_frame,
text="Select Folder:",
font=("Helvetica", 12),
bg="#1f2f3a",
fg="#bdc3c7"
).pack(anchor="w")
self.folder_entry = tk.Entry(
folder_frame,
font=("Helvetica", 14),
width=50
)
self.folder_entry.pack(side="left", pady=5)
tk.Button(
folder_frame,
text="Browse",
command=self.browse_folder
).pack(side="left", padx=5)
What this does
Displays the selected folder path
Opens a folder picker when clicking Browse
π Step 7: Prefix, Suffix, Find & Replace Inputs
options_frame = tk.Frame(self.root, bg="#1f2f3a")
options_frame.pack(pady=10, fill="x", padx=20)
Prefix & Suffix
tk.Label(options_frame, text="Prefix:").grid(row=0, column=0)
self.prefix_entry = tk.Entry(options_frame, width=25)
self.prefix_entry.grid(row=0, column=1)
tk.Label(options_frame, text="Suffix:").grid(row=0, column=2)
self.suffix_entry = tk.Entry(options_frame, width=25)
self.suffix_entry.grid(row=0, column=3)
Find & Replace
tk.Label(options_frame, text="Find:").grid(row=1, column=0)
self.find_entry = tk.Entry(options_frame, width=25)
self.find_entry.grid(row=1, column=1)
tk.Label(options_frame, text="Replace:").grid(row=1, column=2)
self.replace_entry = tk.Entry(options_frame, width=25)
self.replace_entry.grid(row=1, column=3)
These inputs control how filenames will be transformed.
π Step 8: Preview Listbox
Before renaming files, users should see what will happen.
self.preview_listbox = tk.Listbox(
self.root,
font=("Helvetica", 12),
bg="#2c3e50",
fg="white"
)
self.preview_listbox.pack(fill="both", expand=True, padx=20, pady=10)
This shows:
Original filenames
Previewed renamed filenames
π§ͺ Step 9: Preview Changes Logic
def preview_changes(self):
prefix = self.prefix_entry.get()
suffix = self.suffix_entry.get()
find_text = self.find_entry.get()
replace_text = self.replace_entry.get()
self.preview_files = []
for filename in self.files:
new_name = filename
if find_text:
new_name = new_name.replace(find_text, replace_text)
if prefix:
new_name = prefix + new_name
if suffix:
name, ext = os.path.splitext(new_name)
new_name = name + suffix + ext
self.preview_files.append(new_name)
self.update_preview_list(self.preview_files)
Key idea
π Nothing is renamed yet.
We only show a preview so users can double-check.
βοΈ Step 10: Rename Files Safely
def rename_files(self):
if not self.preview_files:
messagebox.showerror("Error", "Preview changes first!")
return
Confirmation dialog
confirm = messagebox.askyesno(
"Confirm",
"Are you sure you want to rename all files?"
)
Perform renaming + save undo history
self.last_rename = []
for old, new in zip(self.original_files, self.preview_files):
if old != new:
os.rename(
os.path.join(self.folder_path, old),
os.path.join(self.folder_path, new)
)
self.last_rename.append((new, old))
β©οΈ Step 11: Undo Last Rename
def undo_rename(self):
if not self.last_rename:
messagebox.showerror("Error", "Nothing to undo.")
return
for current, original in self.last_rename:
os.rename(
os.path.join(self.folder_path, current),
os.path.join(self.folder_path, original)
)
This restores filenames exactly as they were before.
βΆοΈ Step 12: Run the App
if __name__ == "__main__":
root = tk.Tk()
app = FileRenamerApp(root)
root.mainloop()
This launches the GUI window.
π Final Thoughts
You just built a fully functional desktop file renamer with:
GUI layout
File system access
Preview safety
Undo support
Ideas to extend it
Numbered filenames
Regex support
File type filters
Dark/light mode toggle

Top comments (0)