Remember the Last Saved Directory with QFileDialog

How to pre-fill file names and remember the last-used folder in PyQt file dialogs
Heads up! You've already completed this tutorial.

When you use QFileDialog.getSaveFileName() in PyQt6, you can pass a default directory and file name as the third argument. This is great for pointing users to a specific folder, but there's a catch: once you hard-code a directory path, the dialog stops remembering where the user last saved a file.

In this tutorial, we'll look at how to get the best of both worlds — pre-filling a file name from your GUI and remembering the last-used directory between saves.

The Problem

Imagine you have a save dialog that always opens in D:\Data\ and pre-fills the file name from a QLineEdit in your interface:

python
fileName, _ = QFileDialog.getSaveFileName(
    self,
    "Save Measurement",
    'D:\\Data\\' + self.ui.lineEditFileName.text(),
    "(*.csv)",
    options=options,
)

This works, but it always opens in D:\Data\ — even if the user navigated somewhere else during their last save. That's frustrating.

You might have noticed that if you pass an empty string "" as the third argument, QFileDialog automatically remembers the last directory. But then you lose the pre-filled file name. So you're stuck choosing between two useful behaviors.

The solution is to track the last-used directory yourself and combine it with the file name when opening the dialog.

Tracking the Last-Used Directory

The idea is straightforward:

  1. Store the current save folder in an instance variable, starting with your preferred default.
  2. Each time the user saves a file, update that variable with the directory they chose.
  3. When opening the dialog, combine the stored directory with the file name from your GUI.

Let's walk through each piece.

Set a Default Folder

In your window's __init__ method, create an instance variable to hold the active folder. Use a raw string or escape the backslashes on Windows paths:

python
self.active_folder = 'D:\\Data\\'

You could also use a raw string to avoid the double backslashes:

python
self.active_folder = r'D:\Data'

Or, for cross-platform friendliness, use os.path.join:

python
import os
self.active_folder = os.path.join('D:', os.sep, 'Data')

Build the Full Path When Saving

When you open the save dialog, combine self.active_folder with the file name from your QLineEdit using os.path.join():

python
import os

path = os.path.join(self.active_folder, self.ui.lineEditFileName.text())
fileName, _ = QFileDialog.getSaveFileName(
    self,
    "Save Measurement",
    path,
    "(*.csv)",
    options=options,
)

This gives QFileDialog both a directory to open in and a pre-filled file name — exactly what we want.

Update the Folder After Saving

After the user picks a location and confirms the dialog, update self.active_folder with the directory from their chosen path. You should also check that they didn't cancel the dialog (which returns an empty string):

python
if fileName:
    self.active_folder = os.path.dirname(fileName)
    # ... proceed with saving the file

Now the next time the dialog opens, it will start in whatever folder the user last saved to.

Complete Working Example

Here's a full example that puts everything together. It has a QLineEdit for entering a file name and a "Save" button that opens the dialog:

python
import os
import sys

from PyQt6.QtWidgets import (
    QApplication,
    QFileDialog,
    QHBoxLayout,
    QLineEdit,
    QMainWindow,
    QPushButton,
    QVBoxLayout,
    QWidget,
)


class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("Save File Example")

        # Default folder to open in — change this to suit your system.
        self.active_folder = os.path.expanduser("~")

        # Set up the UI.
        self.file_name_input = QLineEdit()
        self.file_name_input.setPlaceholderText("Enter a file name...")
        self.file_name_input.setText("measurement")

        save_button = QPushButton("Save As...")
        save_button.clicked.connect(self.save_file)

        input_layout = QHBoxLayout()
        input_layout.addWidget(self.file_name_input)
        input_layout.addWidget(save_button)

        container = QWidget()
        layout = QVBoxLayout()
        layout.addLayout(input_layout)
        container.setLayout(layout)
        self.setCentralWidget(container)

    def save_file(self):
        # Combine the remembered folder with the file name from the input.
        default_name = self.file_name_input.text()
        path = os.path.join(self.active_folder, default_name)

        file_name, _ = QFileDialog.getSaveFileName(
            self,
            "Save Measurement",
            path,
            "CSV Files (*.csv)",
        )

        if file_name:
            # Update the active folder so next time we open here.
            self.active_folder = os.path.dirname(file_name)

            # This is where you'd actually write your file.
            # For this example, we'll just create an empty file.
            with open(file_name, "w") as f:
                f.write("example,data\n")

            print(f"Saved to: {file_name}")
            print(f"Next dialog will open in: {self.active_folder}")


app = QApplication(sys.argv)
window = MainWindow()
window.show()
app.exec()

Run this, type a file name, and click Save As.... The dialog opens in your home directory (or whatever you set as the default). Navigate to a different folder and save. Click Save As... again — the dialog now opens in the folder you just used, with the file name from the input field already filled in.

Persisting the Folder Between Sessions

The approach above remembers the folder for the lifetime of the application. If you want the folder to persist even after the user closes and reopens the app, you can use QSettings to store it:

python
from PyQt6.QtCore import QSettings

# In __init__, load the saved folder (or use a default):
settings = QSettings("MyCompany", "MyApp")
self.active_folder = settings.value("last_save_folder", os.path.expanduser("~"))

# After a successful save, store it:
if file_name:
    self.active_folder = os.path.dirname(file_name)
    settings = QSettings("MyCompany", "MyApp")
    settings.setValue("last_save_folder", self.active_folder)

QSettings stores values in a platform-appropriate location (the Windows registry, a plist file on macOS, or a config file on Linux), so you don't need to manage config files yourself.

Summary

When you pass a hard-coded path to QFileDialog.getSaveFileName(), the dialog loses its ability to remember the last-used directory. By storing the folder yourself in an instance variable and combining it with os.path.join(), you get full control: a pre-filled file name and a dialog that opens where the user expects it to.

Well done, you've finished this tutorial! Mark As Complete
[[ user.completed.length ]] completed [[ user.streak+1 ]] day streak

Create GUI Applications with Python & Qt6 by Martin Fitzpatrick

(PyQt6 Edition) The hands-on guide to making apps with Python — Over 15,000 copies sold!

More info Get the book

Martin Fitzpatrick

Remember the Last Saved Directory with QFileDialog was written by Martin Fitzpatrick.

Martin Fitzpatrick has been developing Python/Qt apps for 8 years. Building desktop applications to make data-analysis tools more user-friendly, Python was the obvious choice. Starting with Tk, later moving to wxWidgets and finally adopting PyQt. Martin founded PythonGUIs to provide easy to follow GUI programming tutorials to the Python community. He has written a number of popular Python books on the subject.