6

Is there a way in bpy to get a list of all selected files from the file browser?

I have this code, but it is only for the active file selection:

selectedFile = ''
for screenArea in bpy.context.window.screen.areas:
   if screenArea.type == 'FILE_BROWSER':
        params = screenArea.spaces[0].params
        selectedFile = os.path.join(params.directory, params.filename)
        break
MakerDrone
  • 103
  • 1
  • 4

3 Answers3

6

If you take the TextEditor Templates -> Python -> Operator File Import

  • add from bpy.props import CollectionProperty
  • and add this special property in the ImportSomeData operator

inside the importer class

class ImportSomeData(Operator, ImportHelper):

    # edit for brevity

    filename_ext = ".txt"
    files = CollectionProperty(type=bpy.types.PropertyGroup)

Then self.files, with 3 files selected, gives you

... <bpy_collection[3], IMPORT_TEST_OT_some_data.files>
>>> self.files[0]
... <bpy_struct, PropertyGroup("filename_mine2.txt")>

Then to get the fullpath of those files you use the self.path dirname

import os
dirname = os.path.dirname(self.filepath)
for f in self.files:
    print(os.path.join(dirname, f.name))

.../home/zeffii/filename_mine2.txt
.../home/zeffii/record_label_ep2.txt
.../home/zeffii/splines.txt
zeffii
  • 39,634
  • 9
  • 103
  • 186
  • I see, it's the ImportHelper that gives the functionality that I need. I'm not around my computer for now, I will try it when I get a chance. Thank you, that looks promising. – MakerDrone May 11 '15 at 20:05
5

Can use directory in conjunction with files

  • It is also possible to use directory` for the invoked filebrowsers current directory path,

  • and there is a propertygroup type for this already defined as bpy.types.OperatorFileListElement which is basically the same as bpy.types.PropertyGroup by a different name and used the same.

  • Used pathlib over os as another point of difference. https://blender.stackexchange.com/a/167527/15543

These changes applied to Fahads answer https://blender.stackexchange.com/a/183998/15543

import bpy
from pathlib import Path
from bpy_extras.io_utils import ImportHelper 
from bpy.types import Operator, OperatorFileListElement
from bpy.props import CollectionProperty, StringProperty

class OT_TestOpenFilebrowser(Operator, ImportHelper): bl_idname = "test.open_filebrowser" bl_label = "Open the file browser" directory : StringProperty(subtype='DIR_PATH') files : CollectionProperty(type=OperatorFileListElement)

def execute(self, context): 

    &quot;&quot;&quot;Do something with the selected file(s).&quot;&quot;&quot;
    base = Path(self.directory)                
    for f in self.files:
        print(base / f.name)

    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')

batFINGER
  • 84,216
  • 10
  • 108
  • 233
3

A simplified full code sample for better understanding:

import bpy
import os
from bpy_extras.io_utils import ImportHelper 
from bpy.types import Operator
from bpy.props import CollectionProperty

class OT_TestOpenFilebrowser(Operator, ImportHelper): bl_idname = "test.open_filebrowser" bl_label = "Open the file browser"

files : CollectionProperty(type=bpy.types.PropertyGroup) # Stores properties

def execute(self, context): 

    &quot;&quot;&quot;Do something with the selected file(s).&quot;&quot;&quot;

    dirname = os.path.dirname(self.filepath)
    for f in self.files:
        print(os.path.join(dirname, f.name)) #get filepath properties from collection pointer

    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')

  • brilliant. I learned to use CollectionProperty(type=bpy.types.PropertyGroup) there is no such example in the blender help print(f) gives <bpy_struct, PropertyGroup("Untitled-1.py")> where f.name is Untitled-1.py (for noobs like me) – Uneconscience UneSource Jul 29 '20 at 10:37
  • I used it in my addon so now this is possible to install/reload several addons at the same time. https://github.com/1C0D/Addon_Installer-Script_Runner-BlenderAddon/blob/master/Addon_Installer-Script_Runner_v1_1_0_.py – Uneconscience UneSource Jul 29 '20 at 13:36