# Use filemanager to select directory instead of file?

I want my export operator to open the normal file selector but instead of asking for a specific file I want it to ask for a directory. The reason for this is that both my model and the textures should be stored in a directory tree and I want to user to select the root. For example the model file "somemodel.ext" links to the textures "tex1.png" and "tex2.png" the resulting file structure should look like this:

RootFolder
+--textures
+--somemodel
+ tex1.png
+ tex2.png
+--models
+ somemodel.ext


and I want to user to select the RootFolder in the export fileselect.

• Using savePath = bpy.path.abspath('//' + folderName + '/') is working well for me. The textures I'm baking are going into the specified folder which is in the same directory as the .blend. I'll post a more complete code example if no one with more experience shows up with a better solution by tomorrow. – MarcClintDion Aug 5 '14 at 22:06
• I know how to get a folder path but I want the filepicker (the thing that opens when you do Save As... for example) to notice that. And I surely don't want to export the files to a fixed location. But don't mind to post your code, anyway. If you want to discuss this come into the chat chat.stackexchange.com/rooms/8888/the-renderfarm – WorldSEnder Aug 5 '14 at 22:12
• there are a couple Cycles bake Addons that have file selector dialogues. You could dig up one of those for reference. – MarcClintDion Aug 6 '14 at 8:58

The most compact solution that I found uses the method WindowsManager.fileselect_add() in invoke(), and doesn't use the Helpers. The documentation of fileselect_add says:

Opens a file selector with an operator. The string properties ‘filepath’, ‘filename’, ‘directory’ and a ‘files’ collection are assigned when present in the operator

Actually, you need to specify only a directory StringProperty in your operator. In so doing, the possibility to select the name of the file will disappear.

Full example, tested on Blender 2.79:

import bpy

class SelectDirExample(bpy.types.Operator):

"""Create render for all chracters"""
bl_idname = "example.select_dir"
bl_label = "Dir Selection Example Operator"
bl_options = {'REGISTER'}

# Define this to tell 'fileselect_add' that we want a directoy
directory = bpy.props.StringProperty(
name="Outdir Path",
description="Where I will save my stuff"
# subtype='DIR_PATH' is not needed to specify the selection mode.
# But this will be anyway a directory path.
)

def execute(self, context):

print("Selected dir: '" + self.directory + "'")

return {'FINISHED'}

def invoke(self, context, event):
# Open browser, take reference to 'self' read the path to selected
# file, put path in predetermined self fields.
# Tells Blender to hang on for the slow user input
return {'RUNNING_MODAL'}

def register():
bpy.utils.register_class(SelectDirExample)

def unregister():
bpy.utils.unregister_class(SelectDirExample)

#
# Invoke register if started from editor
if __name__ == "__main__":
register()


You can test the manual file selection by hitting SPACE on a 3D view and searching for Dir Selection Example Operator.

Differently, when executed from Python code you can specify the directory on your own: bpy.ops.demo.select_dir_example(directory='/tmp')

• I consider this the better answer now. Btw to show only folders by default you can add a property filter_folder = bpy.props.BoolProperty(default=True, options={'HIDDEN'}). For further reference on options you can set via properties consult the source code. – WorldSEnder Dec 19 '18 at 19:52

I presume the main question here is selecting a root directory with the FileSelector.

bpy_extras.io_utils.ExportHelper includes FileSelectParams, which when set give the desired functionality.

The first attribute to be set is: use_filter_folder = True This will filter anything that is not a folder to the user. This also has the added advantage that the path your script gets back is folder.

You also need to set a file extension type, even though it is not used. It will cause an error on execution. Possible bug? filename_ext = "."

This is based on an for general file import - How do I get the filepath when I import a file?

Full sample

import bpy
from bpy_extras.io_utils import ExportHelper

import os.path

class ExportOperator(bpy.types.Operator, ExportHelper):
"""Operator for setting a directory path."""

#: Name of function for calling the nif export operator.
bl_idname = "export_scene.folder"

#: How the nif import operator is labelled in the user interface.
bl_label = "Export to folder"

filename_ext = "."
use_filter_folder = True

def execute(self, context):
userpath = self.properties.filepath
if(!os.path.isdir(userpath)):
msg = "Please select a directory not a file\n" + userpath
self.report({'WARNING'}, msg)

#Insert the desired logic here to write to the directory.

return{'FINISHED'}

self.layout.operator(
ExportOperator.bl_idname, text="Export Scene to folder")

def register():
bpy.utils.register_module(__name__)

• If the user does decide to enter in a path that is not a directory, then just sanitise with os.path.isdir(file_path). You can only be so defensive. – neomonkeus Aug 6 '14 at 18:20
• You can actually, instead of using ExportHelper, use your own filepath attribute defined as filepath = StringProperty(type='DIR_PATH'). – WorldSEnder Aug 9 '15 at 2:28