Best way for user to specify armature bones?

Best way for user to specify armature bones?

In an add-on script, the user specifies or picks bones of an armature.
What is the best way to do this?

option1 ->EnumProperty lists armature bones

disadvantages:
breaks when user deletes bones.
Won’t it be slow, if an armature has many bones?

option2 ->StringProperty,
But then the user has to enter the bone names by hand.

any help appreciated.

code filters

import bpy


class TESTADDON_PT_main(bpy.types.Panel):
    bl_idname = "TESTADDON_PT_main"
    bl_label = "Test Addon"
    bl_space_type = "VIEW_3D"
    bl_region_type = "UI"
    bl_category = "Test"

    def draw(self, context):
        my_props = context.scene.my_pointer
        col = self.layout.column(align=True)
        col.prop(my_props, "my_armature")
        if my_props.my_armature:
            col.prop(my_props, "my_bone")


def p_filter(self, object):
    return object.type == 'ARMATURE'

def bone_list(self, context, edit_text):
    bone_names = [b.name for b in self.my_armature.data.bones if b.name.startswith(edit_text)]
    return bone_names

class BONES_PG_props(bpy.types.PropertyGroup):
    my_armature: bpy.props.PointerProperty(
        type=bpy.types.Object,
        poll=p_filter,
        )
    my_bone: bpy.props.StringProperty(
        search=bone_list,
        )

classes = [
    TESTADDON_PT_main,
    BONES_PG_props,
    ]

def register():
    for cls in classes:
        bpy.utils.register_class(cls)
    bpy.types.Scene.my_pointer = bpy.props.PointerProperty(
        type=BONES_PG_props
        )

def unregister():
    for cls in classes:
        bpy.utils.unregister_class(cls)
    del bpy.types.Scene.my_pointer

if __name__ == "__main__":
    register()
1 Like

maybe nezumis answer is already enough…but i just wanted to say that you can also create dynmamic enum properties. They don’t have to be static.

From what I understand you will have to update the enum property before use, let it read all scene objects and generate the tuple-list. Right?

Not exactly as best as PointerProperty but it does the job nicely when you need just to reference some object names and use them on the fly, without any need to have raw-references to them.