4

I want the user to be able to select some data from a CollectionProperty

audioFiles = CollectionProperty(type=AudioFileNameGroup)

holding data of a custom PropertyGroup type:

class AudioFileNameGroup(types.PropertyGroup):
    fileName = StringProperty(name="File Name", subtype='FILE_NAME')

To enable the selection for the user, in a panel I'm using prop_search on that:

navStateCol.prop_search(obj, "audioAction", context.scene.frameworkReferences, 'audioFiles', translate=False,
                        icon='PLAY_AUDIO')

but I can't get it to work:

If the obj.audioAction property is a StringProperty

audioAction = StringProperty(name="Audio Effect", subtype='FILE_NAME')

i don't get anything to select from:

no suggestions

This makes sense, as the system has no way of knowing, that it should refer to the fileName StringProperty inside the AudioFileNameGroup.

If the obj.audioAction property is

audioAction = PointerProperty(type=AudioFileNameGroup, name="AudioAction")

it is not editable, and the ui is disabled: disabled ui

How can I use prop_search on the audioFiles collectionproperty?

IARI
  • 245
  • 1
  • 11
  • 2
    As a side note since you are looking at audio files, bpy.path.extensions_audio is a set of audio file extensions supported by the user's blender. – batFINGER Jun 12 '18 at 15:40

2 Answers2

6

Set the name on the collection

Set the name of the collection item, as this is what appears in the prop search. Simple test script, the collection is populated from a simple list.

import bpy

class HelloWorldPanel(bpy.types.Panel):
    """Creates a Panel in the Object properties window"""
    bl_label = "Hello World Panel"
    bl_idname = "OBJECT_PT_hello"
    bl_space_type = 'PROPERTIES'
    bl_region_type = 'WINDOW'
    bl_context = "object"

    def draw(self, context):
        layout = self.layout

        obj = context.object        
        layout.prop_search(obj, "audioAction", context.scene, "audioFiles", icon='SPEAKER')


class AudioFileNameGroup(bpy.types.PropertyGroup):
    name = bpy.props.StringProperty(name="File Name", subtype='FILE_NAME')

def register():       
    bpy.utils.register_class(AudioFileNameGroup)
    audioAction = bpy.props.StringProperty(name="Audio Effect", subtype='FILE_NAME')
    bpy.types.Object.audioAction = audioAction        
    bpy.types.Scene.audioFiles = bpy.props.CollectionProperty(type=AudioFileNameGroup)
    bpy.utils.register_class(HelloWorldPanel)

def unregister():
    # fill this in
    pass

if __name__ == "__main__":
    register()
    items = (
        ('FOO', 'Foo', ''),
        ('BAR', 'Bar', '')
    )
    scene = bpy.context.scene
    for identifier, name, description in items:
        scene.audioFiles.add().name = name
batFINGER
  • 84,216
  • 10
  • 108
  • 233
1

One more example with data-set of strips:

import bpy

class StripListPanel(bpy.types.Panel): bl_label = "Strip List Panel" bl_idname = "UI_PT_StripListPanel" bl_space_type = 'SEQUENCE_EDITOR' bl_region_type = 'UI' bl_category = 'Strip Selector'

@classmethod
def poll(cls, context):
    return context.area.type == 'SEQUENCE_EDITOR'

def draw(self, context):
    layout = self.layout

    scene = context.scene
    ed = scene.sequence_editor

    layout.prop_search(scene, "selectedStrip", ed, "sequences", text="Selected Strip", icon='SEQ_STRIP_DUPLICATE')

def register(): bpy.utils.register_class(StripListPanel) bpy.types.Scene.selectedStrip = bpy.props.StringProperty(name="Selected Strip")

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

del bpy.types.Scene.selectedStrip

if name == "main": register()

tintwotin
  • 2,296
  • 10
  • 24