The Palos Publishing Company

Follow Us On The X Platform @PalosPublishing
Categories We Write About

Build a bulk renaming GUI

Creating a bulk renaming GUI application requires a combination of user interface design and file manipulation logic. Below is a complete example in Python using Tkinter (for GUI) and basic file handling. This app allows users to select a folder, preview the files, define a renaming pattern, and apply the renaming in bulk.


python
import os import tkinter as tk from tkinter import filedialog, messagebox, simpledialog class BulkRenamerApp: def __init__(self, root): self.root = root self.root.title("Bulk File Renamer") self.root.geometry("700x500") self.folder_path = "" self.files = [] # Folder selection frame frame_top = tk.Frame(root) frame_top.pack(pady=10, fill=tk.X, padx=10) self.folder_label = tk.Label(frame_top, text="No folder selected", anchor="w") self.folder_label.pack(side=tk.LEFT, fill=tk.X, expand=True) btn_browse = tk.Button(frame_top, text="Browse Folder", command=self.browse_folder) btn_browse.pack(side=tk.RIGHT) # File listbox frame_list = tk.Frame(root) frame_list.pack(padx=10, pady=10, fill=tk.BOTH, expand=True) scrollbar = tk.Scrollbar(frame_list) scrollbar.pack(side=tk.RIGHT, fill=tk.Y) self.listbox = tk.Listbox(frame_list, selectmode=tk.EXTENDED, yscrollcommand=scrollbar.set) self.listbox.pack(fill=tk.BOTH, expand=True) scrollbar.config(command=self.listbox.yview) # Rename pattern entry frame_bottom = tk.Frame(root) frame_bottom.pack(pady=10, fill=tk.X, padx=10) tk.Label(frame_bottom, text="Rename pattern:").pack(side=tk.LEFT) self.pattern_entry = tk.Entry(frame_bottom) self.pattern_entry.pack(side=tk.LEFT, fill=tk.X, expand=True, padx=5) self.pattern_entry.insert(0, "file_{num}") btn_preview = tk.Button(frame_bottom, text="Preview", command=self.preview_renames) btn_preview.pack(side=tk.LEFT, padx=5) btn_rename = tk.Button(frame_bottom, text="Rename Files", command=self.rename_files) btn_rename.pack(side=tk.LEFT, padx=5) def browse_folder(self): folder = filedialog.askdirectory() if folder: self.folder_path = folder self.folder_label.config(text=folder) self.load_files() def load_files(self): self.files = [] self.listbox.delete(0, tk.END) for filename in os.listdir(self.folder_path): if os.path.isfile(os.path.join(self.folder_path, filename)): self.files.append(filename) self.listbox.insert(tk.END, filename) def preview_renames(self): pattern = self.pattern_entry.get() if not pattern: messagebox.showerror("Error", "Rename pattern cannot be empty") return # Use selected files or all if none selected selected_indices = self.listbox.curselection() if selected_indices: selected_files = [self.files[i] for i in selected_indices] else: selected_files = self.files preview_list = [] for i, filename in enumerate(selected_files, start=1): ext = os.path.splitext(filename)[1] try: new_name = pattern.format(num=i, ext=ext, name=os.path.splitext(filename)[0]) + ext except KeyError: # If user does not use .format() correctly, fallback new_name = f"{pattern}{i}{ext}" preview_list.append(new_name) preview_text = "Preview of new file names:n" + "n".join(preview_list) messagebox.showinfo("Preview", preview_text) def rename_files(self): pattern = self.pattern_entry.get() if not pattern: messagebox.showerror("Error", "Rename pattern cannot be empty") return selected_indices = self.listbox.curselection() if selected_indices: files_to_rename = [self.files[i] for i in selected_indices] else: files_to_rename = self.files # Confirm if not files_to_rename: messagebox.showinfo("Info", "No files to rename.") return confirm = messagebox.askyesno("Confirm", f"Are you sure you want to rename {len(files_to_rename)} files?") if not confirm: return errors = [] for i, filename in enumerate(files_to_rename, start=1): ext = os.path.splitext(filename)[1] base_name = os.path.splitext(filename)[0] try: new_name = pattern.format(num=i, ext=ext, name=base_name) + ext except KeyError: new_name = f"{pattern}{i}{ext}" old_path = os.path.join(self.folder_path, filename) new_path = os.path.join(self.folder_path, new_name) try: if os.path.exists(new_path): raise FileExistsError(f"{new_name} already exists.") os.rename(old_path, new_path) except Exception as e: errors.append(f"Failed to rename {filename}: {e}") if errors: messagebox.showerror("Errors Occurred", "n".join(errors)) else: messagebox.showinfo("Success", f"Renamed {len(files_to_rename)} files successfully.") self.load_files() if __name__ == "__main__": root = tk.Tk() app = BulkRenamerApp(root) root.mainloop()

Features

  • Browse to select folder.

  • Display list of files.

  • Specify a renaming pattern using Python-style .format() placeholders:

    • {num} — incremental number starting from 1

    • {name} — original filename without extension

    • {ext} — file extension including dot (e.g., .txt)

  • Preview new filenames before applying.

  • Rename selected files or all files.

  • Simple error handling (e.g., conflicts).

Example rename pattern

  • file_{num} → file_1.txt, file_2.jpg

  • {name}_backup_{num} → original_backup_1.txt, another_backup_2.jpg


If you’d like, I can help extend this with more advanced features such as regex renaming, undo functionality, or other enhancements!

Share this Page your favorite way: Click any app below to share.

Enter your email below to join The Palos Publishing Company Email List

We respect your email privacy

Categories We Write About