pythontkinterfiledialoglistdir

Program to copy, rename, and paste files. tkinter listdir error: path should be string, bytes, os.Pathlike or None


I am in the process of creating a program that prompts for source folder, destination folder, old text string, and new text string and then copies, renames, and pastes files from the source folder to the destination folder. Here is my code:

#Imports
import tkinter as tk
from tkinter import filedialog
import shutil
import os

#Define functions to handle folder selections
def select_folder1():
    source_folder = filedialog.askdirectory()
    print ("Source folder: ", source_folder)

def select_folder2():
    destination_folder = filedialog.askdirectory()
    print ("Destination folder: ", destination_folder)

#Milestone 1: Create GUI (a tkinter window)
window = tk.Tk()
window.title("File Copier and Renamer")
window.geometry("400x300")

#Milestone 2: Declare inputs and output variables.
old_text=tk.StringVar()
new_text=tk.StringVar()
source_folder=tk.StringVar()
destination_folder=tk.StringVar()

#Create a button to browse for first folder.
browse_button = tk.Button(window, text="Select old folder",command=select_folder1)
browse_button.pack(padx=10, pady=10)
print ("source folder: ", source_folder)

#Create a button to browse for second folder.
browse_button = tk.Button(window, text="Select new folder",command=select_folder2)
browse_button.pack(padx=10, pady=10)
print ("dest folder: ", destination_folder)

#Add input boxes to allow for text entry.
label = tk.Label(text="Enter text to remove from filename.")
label.pack()
old_text = tk.Entry(window,textvariable=old_text)
old_text.pack()
print(old_text)
label = tk.Label(text="Enter text to add to filename.")
label.pack()
new_text = tk.Entry(window,textvariable=new_text)
new_text.pack()
print(new_text)

#Milestone 5: Develop function to handle the copy, rename, and paste of files.
def crp(source_folder,destination_folder):
    print ("in crp")
    for filename in os.listdir(source_folder):
        print ("in for loop")
        source_file_path = os.path.join(source_folder, filename)
        print ("source file:", source_file)
        new_filename = file.replace(old_text,new_text)
        print ("new filename:", new_filename)
        destination_file_path = os.path.join(destination_folder, filename)
        print ("dest file:", destination_file)
        shutil.copy(source_file_path, destination_file_path)
        print ("copied file")

big_green_button = tk.Button(
    text="Copy, rename, and paste files.",
    bg="green",
    fg="white",
    command=lambda: crp (source_folder,destination_folder)
    )
big_green_button.pack(padx=10, pady=10)

#Milestone 6: Develop code to end session.
close_button = tk.Button(window, text="Close",command=window.destroy)
close_button.pack()

#Main loop
window.mainloop()

#Programmer notes: Don't forget to rename the script .pyw so the
#console window does not show.

I tried declaring the source_folder and destination_folder variables as global within the crp function, but that broke the program. I also tried changing StringVar to String where I declared them outside of the function originally. This also caused the program to not run. I'm using Atom IDE.


Solution

  • Solution:

    Hi, the problem is that you have defined StringVar's where you have to use set to change the value of the variable and get to read the value. If you change the code for this you will get further.

    Hint:

    Some of your other variables are not correctly named yet (quickly to see after the main fix). There is also a reasonable approach (many examples in internet) where you can define your tkinter application as object oriented which would help you to avoid global variables.