I'm trying to write a custom operator for Blender that:
- Gets the objects currently in the scene (may be lots)
- Filters them based on some criteria
- Prompts the user to select/deselect any of the filtered objects (using checkboxes or similar)
- Does something with the final selection.
I'm stuck on number 3. I'd like to show the user a window with checkboxes beside each of the filtered options, but to do that I'd have to be able to generate the properties dynamically.
The closest thing I've found so far is a bpy.props.EnumProperty, which takes callable to set its items. But it only supports 1 selection, whereas I need the user to be able to select multiple options.
Example:
def filter_objects(self, context):
return [obj for obj in bpy.data.objects if obj.name.startswith('A')]
class TurnObjectsBlue(bpy.types.Operator):
'TurnObjectsBlue'
bl_idname = 'object.turnobjectsblue'
bl_label = 'TurnObjectsBlue'
bl_options = {'REGISTER'}
# MultiSelectCheckboxes doesn't exist :(
chosen_objects: bpy.props.MultiSelectCheckboxes(
name='Select Objects',
)
def execute(self, context):
from coolmodule import turn_blue
for obj in self.user_selected_objects:
turn_blue(obj)
return {'FINISHED'}
def invoke(self, context, event):
return context.window_manager.invoke_props_dialog(self)
It looks like you want a
CollectionProperty
. These are basically native blender lists that can store blender properties, and can have as many items as you like.To set one up, start by creating a new class that will represent one of the items in the
CollectionProperty
. It should inherit frombpy.types.PropertyGroup
, and in it you can define any properties that you want to be able to access (also make sure to register that class):Then you can rewrite your operator to do something like this:
While collection properties can act like Blender lists, they work fairly differently to python lists, so I'd suggest reading a bit about them to try and understand how they work: https://docs.blender.org/api/current/bpy.props.html#collection-example
Hope that helps!