Using Blender’s filebrowser with Python

16.04.2018 @ Tutorials(Blender, Python)

Every now and then an addon requires that the user selects a spe­cif­ic file or path. Sure, you could just give users a sim­ple string input and let them copy/paste into it but how much cool­er would it be to let them pick a file from the file­brows­er?

Luckily Blender pro­vides a handy class that does almost every­thing for us.

Meet ImportHelper

Importhelper is a mix-in class found in the bpy_extras sub­mod­ule. It includes an invoke() func­tion that calls the file­brows­er and a few helper func­tions used in Blender’s importer addons. To use it all we have to do is extend it in our oper­a­tor. Let’s start by import­ing both ImportHelper and Operator.

from bpy_extras.io_utils import ImportHelper
from bpy.types import Operator

Now we can go ahead and cre­ate the oper­a­tor:

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 oper­a­tor already has an invoke() func­tion that calls the file­brows­er and when a user selects a file, it stores the file’s path in self.filepath. Note that this is a reg­u­lar StringProperty inside ImportHelper that we inher­it­ed when we sub­classed it.


To fil­ter the types of files shown to the user we have to add a filter_glob prop­er­ty to our class. This is a StringProperty with the list of exten­sions we want to show. Each exten­sion is writ­ten in wild­card style and is sep­a­rat­ed by a semi-colon. Note that strings longer that 255 could be cut (since that’s the inter­nal buffer size).

filter_glob: StringProperty(
    default='*.jpg;*.jpeg;*.png;*.tif;*.tiff;*.bmp',
    options={'HIDDEN'}
)

Also keep in mind that users can dis­able fil­ter­ing in the UI and select any kind of file. You might want to reject a file or do some­thing dif­fer­ent depend­ing on the exten­sion you receive. You can take care of that with good old spli­text().

filename, extension = os.path.splitext(self.filepath)

And what about adding set­tings to the file­brows­er screen? All you have to do is add prop­er­ties to the oper­a­tor as usu­al and they will show up in the brows­er.

    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 util­i­ties to check for exist­ing files and set­ting a default unti­tled file­name in the brows­er.

Did I miss some­thing? Let me know in the com­ments!

All the posts you can read

3 Comments

  1. Vnny(5 months ago)

    script worked fine, but I still cant build a blender script with a but­ton for import file and one for export file! I just cant seem to get but­tons to work for me to open any­thing oth­er than blenders inten­tions, like “render.render” ! 5 days now and still cant get my head around it, but this is by far the best site vis­it­ed, nice and clean look­ing easy to fol­low.

    1. Diego Gangl(5 months ago)

      Hi Vnny, thanks for the com­ments! If you want to cre­ate cus­tom but­tons; you need to cre­ate, and reg­is­ter, your own oper­a­tors and then add them to a pan­el as but­tons (I assume that’s what you mean by Blender’s inten­tions).

  2. David John Hawley(4 months ago)

    One thing I can’t fig­ure out is how to get the result of the file dia­log back.
    I want to get a file­name in order to do some­thing, let’s call it ActualOperation(myObject), where myObject is an ElementTree.
    The exam­ples all show the oper­a­tion using the filepath to do ActualOperation, but as argu­ments are passsed in as prop­er­ties, and only sim­ple types are allowed, that is not pos­si­ble.
    So I want to do the obvi­ous, which is get the filepath back from the file dia­log some­how.

Leave a Reply

Your email address will not be published.