Can I get some syntax help?

I don’t do much in the way of python, so I always seem to run into these issues. I have an armature with a large number of bones that I would like to assign a custom object. I would like to simply select those bones and run the script. This is what I have, but I get an error.


import bpy
for a in bpy.context.selected_objects:
    a.custom_shape = bpy.data.objects["gzmo_spine_detail"]

In this case, I want each selected bone to use the object “gzmo_spine_detail”

The console output when I do each one manually looks like this:


bpy.context.object.pose.bones["Bone.043"].custom_shape = bpy.data.objects["gzmo_spine_detail"]

Thanks for any help!

According to your first line, you ask for “a” to be an object. What you really want is actually “bone”.

You have to use “bpy.context.selected_bones” and/or “bpy.context.selected_pose_bones” to get every bones selected. They’re respectably used for “edit” and “pose” mode.
To know what mode is actually used, it’s in “bpy.context.mode”.

EDIT : After verification, only “bpy.context.selected_pose_bones” give possibility to use custom_shape afterwards.

This should work:


import bpy

bone_object = bpy.data.objects["gzmo_spine_detail"]

for ob in bpy.context.selected_objects:
    if ob.type == 'ARMATURE':
        ob.data.show_bone_custom_shapes = True
        for bone in ob.pose.bones:
            bone.custom_shape = bone_object

Thank you for the responses, I suspected that I needed to access the bones differently, but wasn’t sure where to look.

The code from CoDEmanX is very close to what I need, so I think I can adjust from here. (that code changes all bones in the armature, not just the selected ones.)

I think I just need to change “for bone in ob.pose.bones:” to something that only cycles through the selected bones.