Using Blender's filebrowser with Python
Every now and then an addon requires that the user selects a specific file or path. Sure, you could just give users a simple string input and let them copy/paste into it but how much cooler would it be to let them pick a file from the filebrowser?
Luckily Blender provides a handy class that does almost everything for us.
Meet ImportHelper
Importhelper is a mix-in class found in the bpy_extras submodule. It includes an invoke() function that calls the filebrowser and a few helper functions used in Blender’s importer addons. To use it all we have to do is extend it in our operator. Let’s start by importing both ImportHelper and Operator.
from bpy_extras.io_utils import ImportHelper
from bpy.types import Operator
Now we can go ahead and create the operator:
class OT_TestOpenFilebrowser(Operator, ImportHelper):
bl_idname = "test.open_filebrowser"
bl_label = "Open the file browser (yay)"
def execute(self, context):
"""Do something with the selected file(s)."""
return {'FINISHED'}
Yup, that’s it. Our new operator already has an invoke() function that calls the filebrowser and when a user selects a file, it stores the file’s path in self.filepath. Note that this is a regular StringProperty inside ImportHelper that we inherited when we subclassed it.
To filter the types of files shown to the user we have to add a filter_glob property to our class. This is a StringProperty with the list of extensions we want to show. Each extension is written in wildcard style and is separated by a semi-colon. Note that strings longer that 255 could be cut (since that’s the internal buffer size).
filter_glob: StringProperty(
default='*.jpg;*.jpeg;*.png;*.tif;*.tiff;*.bmp',
options={'HIDDEN'}
)
Also keep in mind that users can disable filtering in the UI and select any kind of file. You might want to reject a file or do something different depending on the extension you receive. You can take care of that with good old splitext().
filename, extension = os.path.splitext(self.filepath)
And what about adding settings to the filebrowser screen? All you have to do is add properties to the operator as usual and they will show up in the browser.
some_boolean: BoolProperty(
name='Do a thing',
description='Do a thing with the file you\'ve selected',
default=True,
)
Final code
import bpy
import os
from bpy.props import StringProperty, BoolProperty
from bpy_extras.io_utils import ImportHelper
from bpy.types import Operator
class OT_TestOpenFilebrowser(Operator, ImportHelper):
bl_idname = "test.open_filebrowser"
bl_label = "Open the file browser (yay)"
filter_glob: StringProperty(
default='*.jpg;*.jpeg;*.png;*.tif;*.tiff;*.bmp',
options={'HIDDEN'}
)
some_boolean: BoolProperty(
name='Do a thing',
description='Do a thing with the file you\'ve selected',
default=True,
)
def execute(self, context):
"""Do something with the selected file(s)."""
filename, extension = os.path.splitext(self.filepath)
print('Selected file:', self.filepath)
print('File name:', filename)
print('File extension:', extension)
print('Some Boolean:', self.some_boolean)
return {'FINISHED'}
def register():
bpy.utils.register_class(OT_TestOpenFilebrowser)
def unregister():
bpy.utils.unregister_class(OT_TestOpenFilebrowser)
if __name__ == "__main__":
register()
# test call
bpy.ops.test.open_filebrowser('INVOKE_DEFAULT')
There’s also an ExportHelper class that includes some utilities to check for existing files and setting a default untitled filename in the browser.
Did I miss something? Let me know in the comments!