open KNOWNFOLDERID with askopenfilename in Tkinter / Python

125 Views Asked by At

I want to set my initialdir to a KNOWNFOLDERID like Documents or Desktop. Is this even possible? I tried like this, but instead it open up the directory of my python project.

from tkinter import *
from tkinter import filedialog

root = Tk()

root.filename = filedialog.askopenfilename(
    initialdir="%USERPROFILE%/Documents",
    title="get a file",
    filetypes=((".jpg files", "*.jpg"), (".png files", "*.png")) 
)

root.mainloop()
2

There are 2 best solutions below

1
scotty3785 On BEST ANSWER

You can use pathlib's home if you just need the user's directory.

To get the path of the documents folder use

from pathlib import Path

docs_folder = Path.home() / "Documents"

This will work both on Windows and Unix based OS.

Alternatively you can use expandvars from os.path

import os
docs_folder = os.path.join(os.path.expandvars('%USERPROFILE%'),'Documents')
0
User9314751 On

In Windows, using Path.home() from pathlib you get the enviroment string %USERPROFILE%, but the path of the Documents folder may not be %USERPROFILE%\Documents, since its location is editable by the user.

If the KnownFolderID has an equivalent CLSID, you can use the SHGetFolderPathW function with the ctypes library. For example, to get the Documents folder path:

import ctypes

ptr = ctypes.create_unicode_buffer(260)
ctypes.windll.shell32.SHGetFolderPathW(None, 5, None, 0, ptr)
folder_path = ptr.value

The second argument is the CLSID enum. For example Documents = 5, Desktop = 16, UserProfile = 40. The third parameter is if you want the folder current path (0) or the folder default path (1).

With ctypes it should be also possible to retrieve the path of the other KnownFolderID (those that don't have a clsid equivalent) defining a structure, and that would answer this question completely. If I manage to do it, I'll update this reply.