Introduction
In this lesson, we are gonna solve a real-life problem using a python program. Let's discuss the problem first. You may have seen the names of some files are too lengthy and spiny for remembering. Especially for the files downloaded from the Whatsapp Web. Because the name of images and videos downloaded from there look almost similar except for some small changes.
In this case, the problem occurs when we try to find a specific file among a large number of similar file types. To solve this problem, I created the python project to help us get rid of this weird situation. It will Rename Multiple Files using Python in one go.
This File Renamer can be used by anyone because of its' easy graphical interface. One more important point is, users can rename any type of file(any extensions) using it. I've kept everything tidy and clean so that even the school-level programmer can understand it.
Please have a look at how this application works.
☛Visit Also: Junk File Organizer in Python (Organize a Messy Folder)
How does the File Renamer Application work?
The graphics of this Python File Renamer is managed by the Tkinter library. It let users select the files individually or the folder where the files are situated(Users need to select the file type before through the Combobox). The file names will be displayed in the Tkinter Listbox. I've added an option to add more files or delete a file from the Listbox.
Next, users have to select or mention the path where the renamed files will be saved. One more step is there(it is optional); users can set the base name of every renamed file through the Tkinter Entry box.
Now the final step comes; Start Renaming Operation. The status('Not Started Yet', 'Renaming...', or 'Renaming Completed') of this operation will display on a label side-by-side.
Let's see this output video to know how the File Renamer program really works.
Requirements
☛Install Tkinter: pip install tk
Import the modules
Let's create a Python file with the name "File_Renamer.py" and start writing the code by importing these modules. You can choose another name as your choice. I kept this name by following the objectives of the program.
import os
import glob
from tkinter import *
from threading import *
from PIL import ImageTk, Image
from tkinter import messagebox, ttk, filedialog
Declare a Python List
Declare a python list that contains the file extensions. I've added some frequently used extensions here. You can modify it as per your requirements.
There is a Combobox('self.File_Type') on the main page(or 'self.frame_2') that offers to select the file type. When you'll change the data from this 'file_types' list, it will automatically change the available choices in that Combobox.
# Modification can be performed here.
# File Extensions: You can modify it as per your recuirements
file_types = ['.jpg', '.jpeg', '.png', '.mp3', '.mp4', '.pdf']
Declare the 'File_Renamer' class
Now declare the 'File_Renamer' class.
class File_Renamer:
Declare the __init__() function
It will create a GUI window for us. We set the window size, title, background color, resizable option, etc. here. In this function, I've declared two Tkinter frames, two buttons, and some variables that are gonna used in the upcoming program. Later this function calls the 'Main_Page()' and 'Display_Logo()' functions.
def __init__(self, root):
# Setting the Tkinter main window
self.window = root
self.window.geometry("720x500")
self.window.title('File Renamer - PySeek')
self.window.resizable(width = False, height = False)
self.window.configure(bg='gray90')
# Declaring some variables
self.Selected_Folder = ''
self.SaveTo_Loc = ''
self.File_List = list()
# Python Dictionary to store the file name corresponding
# with the file path
self.File_Dict = dict()
# Frame 1: For the Logo
self.frame_1 = Frame(self.window,bg='gray90',\
width=280, height=70)
self.frame_1.pack()
self.frame_1.place(x=20, y=20)
# Calling the function to display the logo
self.Display_Logo()
# About Button
About_Btn = Button(self.window, text="About", \
font=("Kokila", 10, 'bold'), bg="dodger blue", \
fg="white", width=5, command=self.About_Window)
About_Btn.place(x=600, y=20)
# Exit Button
Exit_Btn = Button(self.window, text="Exit", \
font=("Kokila", 10, 'bold'), bg="dodger blue", \
fg="white", width=5, command=self.Exit_Window)
Exit_Btn.place(x=600, y=60)
# Frame 2: For the Main Page Widgets
self.frame_2 = Frame(self.window, bg="white",\
width=720,height=480)
self.frame_2.place(x=0, y=110)
# Calling the function to display main page
# widgets
self.Main_Page()
Display the logo
This function displays a logo in the header section of the window. It gives the application a pro look. Here, the image location(or path) is mentioned in the Image.open() function. The image file must need to present there; otherwise, the program will give an error message.
# This function displays the File Renamer Logo
def Display_Logo(self):
# Opening the logo image
image = Image.open('Images/File_Renamer.png')
# Resizing the image
resized_image = image.resize((280, 70))
# Create an object of tkinter ImageTk
self.img_1 = ImageTk.PhotoImage(resized_image)
# Create a Label Widget to display the text or Image
label = Label(self.frame_1, bg='gray90',image=self.img_1)
label.pack()
The main page
The main page function adds all the widgets related to renaming multiple files. I've declared one single comment line before each segment of the code. It will help you to understand the objectives of the program better.
Let's declare a combobox to add the file extensions from the pre-declared python list('file_types').
# This function displays all the widgets in the 'self.frame_2'
# related to File Renaming Operation
def Main_Page(self):
Filetype_Label = Label(self.frame_2, text="File Type: ", \
font=("Kokila", 12, 'bold'), bg='white')
Filetype_Label.place(x=50, y=30)
self.f_type = StringVar()
# Combo Box for showing the file extensions
self.File_Type = ttk.Combobox(self.frame_2, \
textvariable=self.f_type, font=("times new roman",13),width=8)
self.File_Type['values'] = file_types
self.File_Type.current(0)
self.File_Type.place(x=150,y=30)
Add the select folder button and the entry widget for showing the selected directory path.
# Button for selecting the directory(where
# the desired files are presented)
Folder_Button = Button(self.frame_2, text="Select Folder", \
font=("Kokila", 10, 'bold'), bg="gold", width=10, \
command=self.Select_Directory)
Folder_Button.place(x=20, y=70)
# The directory path selected from the Tkinter file dialog
# that opens by the 'Folder_Button' is displayed here.
self.Folder_Entry = Entry(self.frame_2, \
font=("Helvetica", 12), width=30)
self.Folder_Entry.place(x=150, y=75)
Now add another button for choosing the Save To path through the file dialog. We'll add an entry widget on just the right side of the button for showing the path. Users can enter the path to it instead of selecting through the button.
# Button for selecting the directory where the
# renamed file will be stored.
SaveTo_Button = Button(self.frame_2, text="Save To", \
font=("Kokila", 10, 'bold'), bg="green", fg='white', \
width=10, command=self.SaveTo_Directory)
SaveTo_Button.place(x=20, y=125)
# The directory path selected from the Tkinter file dialog
# that opens by the 'SaveTo_Button' is displayed here.
self.SaveTo_Entry = Entry(self.frame_2, \
font=("Helvetica", 12), width=30)
self.SaveTo_Entry.place(x=150, y=130)
Create a label and entry widget to take the base name of each renamed file from the user. It's optional. If the user doesn't enter any name here, the renamed file will be saved to this sequential numbers: 0.ext, 1.ext, 2.ext, and so on. Here ext can be any extension depending on the preference of the user.
ResultFile_Label = Label(self.frame_2, \
text="Result File: ", font=("Kokila", 12, 'bold'), bg='white')
ResultFile_Label.place(x=35, y=175)
# Tkinter Entry widget that let users enter the Base Name
# for every Result file. It is optional
self.ResultFile_Entry = Entry(self.frame_2, \
font=("Helvetica", 12))
self.ResultFile_Entry.place(x=150, y=175)
Create a status label for showing the current status of the operation('Not Started Yet', 'Renaming...', or 'Renaming Completed').
Status = Label(self.frame_2, text="Status: ", \
font=("Kokila", 12, 'bold'), bg='white')
Status.place(x=70, y=215)
# Status Label:
# Options: 'Not Slected(By Default), or 'Renaming...',
# or 'Renaming Completed''
self.Status_Label = Label(self.frame_2, text="Not Started Yet", \
font=("Kokila", 12), bg="white", fg="red")
self.Status_Label.place(x=150, y=215)
Let's create a Start button for starting the Renaming operation.
# Start Button: Users have to press this button
# to start renaming operation
Start_Button = Button(self.frame_2, text="Start", \
font=("Kokila", 13, 'bold'), bg="dodger blue", fg="white", \
width=8, command=self.Threading)
Start_Button.place(x=120, y=260)
Add a Label(for the heading of the Listbox) and a Tkinter Listbox to show the name of the selected files.
# Listbox for showing the selected files for renaming
self.File_ListBox = Listbox(self.frame_2,width=30, height=14)
self.File_ListBox.place(x=450, y=60)
Add two more buttons for adding more files to the Listbox and delete files from there.
# Users can add more files or files(files that will be renamed)
# to the ListBox using this Add_Button
Add_Button = Button(self.frame_2, text='Add', \
font=("Kokila", 9, 'bold'), width=6, command=self.Add_File)
Add_Button.place(x=450, y=322)
# Users can delete a selected file from the ListBox
Delete_Button = Button(self.frame_2, text='Delete', \
font=("Kokila", 9, 'bold'), width=6, command=self.Delete_File)
Delete_Button.place(x=530, y=322)
Select the directory
'Select_Directory()' function let users select the folder(through file dialog) where all the desired files are situated. When the 'Folder_Button' is pressed this function gets a call.
# This function opens the Tkinter file dialog to
# let users select the directory where the files are presented
def Select_Directory(self):
# Storing the 'saving location' for the result file
self.Clear_Listbox()
self.Selected_Folder = filedialog.askdirectory(title = \
"Select a location")
self.Folder_Entry.insert(0, self.Selected_Folder)
# If the user selects a directory
if self.Selected_Folder != '':
self.Files_in_Listbox()
Choose the Save To location
'SaveTo_Directory()' function allows users to select the directory(through file dialog) where they want to save the renamed files after completing the renaming operation.
# This function opens the Tkinter file dialog to let users
# to select the directory where the result file will be saved
def SaveTo_Directory(self):
self.SaveTo_Loc = filedialog.askdirectory(title = \
"Select a location")
self.SaveTo_Entry.insert(0, self.SaveTo_Loc)
Display the file names in the Tkinter Listbox
Here, I've declared a function called 'Files_in_Listbox()' that adds only the file's name to the Listbox. First, the function tries to find only the specific file types(as the user has chosen) using the glob function in the directory the user has selected before; later it stores the path of the matching files to the 'self.File_List' list.
Then it displays only the file name from each path that is already stored in that list('self.File_List'). Here, I've added the filename and the corresponding path to a python dictionary(name: 'self.File_Dict') for performing the Add More and Delete operations later.
# This function adds only the file name to the Tkinter ListBox
def Files_in_Listbox(self):
self.File_List = \
glob.glob(f"{self.Selected_Folder}/*{self.File_Type.get()}")
for path in self.File_List:
# Storing the file name with the corresponding file
# path to the 'self.File_Dict' dictionary
self.File_Dict[os.path.basename(path)] = path
self.File_ListBox.insert(END, os.path.basename(path))
Add more files to the Listbox
This function allows users to add more similar files to the Listbox as well as updates the pre-declared 'self.File_List' list and 'self.File_Dict' dictionary also by adding the file path and name.
# This function adds files to the 'self.File_ListBox',
# 'self.File_List', and 'self.File_Dict'
def Add_File(self):
File_Path = filedialog.askopenfilenames(initialdir = "/", \
title = "Select PDF Files", filetypes = \
((f"{self.File_Type.get()} files",f"*{self.File_Type.get()}*"),))
for Path in File_Path:
# Adding the file path to the 'self.File_List'
self.File_List.append(Path)
# Adding the file name(as Key) and path(as Value)
# to the 'self.File_Dict'
self.File_Dict[os.path.basename(Path)] = Path
# Adding the File Name to the ListBox
self.File_ListBox.insert(END, os.path.basename(Path))
Delete files from the Listbox
This function does the same task as the previous but the delete operation instead of the add operation.
# This function does the Delete operation as the
# previous one instead of the Add Operation
def Delete_File(self):
try:
if len(self.File_List) < 1:
messagebox.showwarning('Warning!', \
'There is no more files to delete')
else:
for item in self.File_ListBox.curselection():
self.File_List.remove(\
self.File_Dict[self.File_ListBox.get(item)])
self.File_Dict.pop(self.File_ListBox.get(item))
self.File_ListBox.delete(item)
except Exception:
messagebox.showwarning('Warning!',"Please select PDFs first")
Clear the Listbox
The 'Clear_Listbox()' function clears the list box as well as resets all the pre-declared variables and entry widgets, and the status label.
# It clears the 'self.File_ListBox' and resets
# some python variables and Tkinter widgets
def Clear_Listbox(self):
self.File_List.clear()
self.File_Dict.clear()
self.Selected_Folder = ''
self.SaveTo_Loc = ''
self.Status_Label.config(text="Not Started Yet")
self.Folder_Entry.delete(0, END)
self.SaveTo_Entry.delete(0, END)
self.ResultFile_Entry.delete(0, END)
self.File_ListBox.delete(0, END)
Create a different Thread and call the 'Rename_Files' function
The 'Threading()' function creates a different thread to call 'Rename_File()' function that performs the renaming operation. I've added the necessary comment lines before each segment of the code. I hope it will help you to grab the logic of this part clearly.
# Creating a different thread to run the 'Download' function
def Threading(self):
# Killing a thread through "daemon=True" isn't a good idea
self.x = Thread(target=self.Rename_Files, daemon=True)
self.x.start()
# This function performs the renaming operation
def Rename_Files(self):
# If no files are peresented in the 'self.File_List'
# a Tkinter MessageBox will pop up
if len(self.File_List) == 0:
messagebox.showerror('Error!', "There are no files to rename")
else:
# If the user doesn't select the Saving Location
# a warning message will display
if self.SaveTo_Entry.get() == '':
messagebox.showwarning('Warning!', \
"Please Select a Save Location")
else:
# If the user doesn't enter the Base File Name
if self.ResultFile_Entry.get() == '':
self.Status_Message(status = 'Renaming...')
for file in self.File_List:
source = file
Part1 = self.SaveTo_Entry.get()
Part2 = self.File_List.index(file)
Part3 = self.File_Type.get()
destination = f"{Part1}/{Part2}{Part3}"
# Calling the os.rename function
os.rename(source, destination)
self.Clear_Listbox()
self.Status_Message(status = 'Renaming Completed.')
self.Done_Message()
else:
# If the user entered the Base File Name
self.Status_Message(status = 'Renaming...')
for file in self.File_List:
source = file
Part1 = self.SaveTo_Entry.get()
Part2 = self.ResultFile_Entry.get()
Part3 = self.File_List.index(file)
Part4 = self.File_Type.get()
destination = f"{Part1}/{Part2}_{Part3}{Part4}"
# Calling the os.rename function
os.rename(source, destination)
self.Clear_Listbox()
self.Status_Message(status = 'Renaming Completed.')
self.Done_Message()
The miscellaneous functions
This function displays the current status of the renaming operations(mentioned above). I've used python kwargs(**Status) here to reduce the redundancy of the code.
# It displays the current status of the Renaming operation
def Status_Message(self, **Status):
for key, value in Status.items():
self.Status_Label.config(text=value)
The 'Done_Message()' function is called when the renaming operation completes.
# When the renaming operation is complete, it displays a
# Done message
def Done_Message(self):
messagebox.showinfo('Done!',"The files are renamed successfully")
I hope the names of the rest of the two functions will indicate you know the objectives of those two.
# When the 'About' button is pressed, this function gets a call
def About_Window(self):
messagebox.showinfo("File Renamer 22.05",\
"Developed by Subhankar Rakshit\n~PySeek")
# This function closes the main window
def Exit_Window(self):
self.window.destroy()
The main function
Now declare the main function. Here, we will create a Tk() class object, and a 'File_Renamer' class object. The Tkinter event loop(mainloop) will start running from here.
# The main function
if __name__ == "__main__":
root = Tk()
# Creating a 'File_Renamer' class object
obj = File_Renamer(root)
root.mainloop()
Download the Project
Download the source code from my GitHub page(https://github.com/subhankar-rakshit) through the download button.
Conclusion
In this lesson, we build a project for Renaming Multiple Files using Python. Users can use this application to rename any type of file(or extensions) using this Application. It can be used by anyone, because of its' easy graphical interface. The graphics of this File Renamer has been managed by the Python Tkinter library.
I hope you enjoyed this tutorial. You're also welcome to give me any further suggestions to improve this Application. You can share your opinion in the comment section.
Thanks for reading!💙
PySeek