Search code examples
pythonfiletkinterdirectory

How can I remember the paths of 'askopenfilenames' & 'askdirectory'?


I'm writing a custom script for Substance Designer which uses Python & Tkinter. The main idea of it is that once the user presses the button, it opens up a window asking you to select the files you need -> [process stuff happens] -> and finally another window opens up asking you the directory you want to save the processed files into.

The problem I'm facing is that whenever I want to repeat this process, the first window (the ones asking me to select my files) opens up in the last place I've been (the directory I saved the files to). The same thing happens when the second window pops up, it opens on the last place I've been (the directory where I've selected the files from).

What I want to happen is for each one of those window pop-ups to always open to the path where that specific functions has happend. So whenever you repeat this process, the first window should directly open with the path the user selected the files from, and the second window should directly open with the path where the user saved those files last time.

The way I'm handling these functions right now is pretty simple, by using:

fileNames = fd.askopenfilenames(parent=root, title='Choose your files')

and

folder_selected = fd.askdirectory()

Where fileNames is the window which asks you to select your files, and folder_selected is the place the user wants those processed files to be saved to.

Any ideas on how I could implement some sort of "memory" thing for those functions, and have the script do what I explained above?


Solution

  • You can use the initialdir parameter to set the initial directory of the filedialog.

    Save the directory opened by the first filedialog to a variable, and the directory opened by the second filedialog to another variable and use those accordingly in the initialdir parameter.

    You can use the os module:

    os.path.dirname("Your Path")
    

    Edit

    You can use a class and set instance/class variables as needed. Here is a simple example:

    import tkinter as tk
    from tkinter import filedialog
    import os
    
    class FileSelectorApp(tk.Tk):
        def __init__(self):
            super().__init__()
            self.src_files = None
            self.dst_files = None
            
            self.title("File Selector")
            
            tk.Button(self, text="Open Files", command=self.open_files).pack()
            tk.Button(self, text="Open Directory", command=self.open_directory).pack()
            
        def open_files(self):
            files = filedialog.askopenfiles(
                title="Select Files", initialdir=self.src_files,
                filetypes=[("All Files", "*.*")]
            )
            if files:
                self.src_files = os.path.dirname(files[0].name)
            
        def open_directory(self):
            directory = filedialog.askdirectory(initialdir=self.dst_files, 
                                                title="Select Directory")
            if directory:
                self.dst_files = os.path.dirname(directory)
            
    
    if __name__ == "__main__":
        app = FileSelectorApp()
        app.mainloop()
    

    You can also create a class to implement the behavior. An object that gets the fd wanted function and manage the directory variable each time the function is called instead of implement this mechanism every time you want to open the fd.