Take the 2-minute tour ×
Blender Stack Exchange is a question and answer site for people who use Blender to create 3D graphics, animations, or games. It's 100% free, no registration required.

In my addon panel, how can I have an object selection box? And what data type would I use to store the the selected object?

It should look like this:

enter image description here

share|improve this question

2 Answers 2

Use prop_search(), a StringProperty and a CollectionProperty.

import bpy

enum_items = (
    ('FOO', 'Foo', ''),
    ('BAR', 'Bar', '')
)

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

        col = layout.column()        
        col.prop_search(context.scene, "coll_string", context.scene, "coll", icon='OBJECT_DATA')

def populate_coll(scene):
    bpy.app.handlers.scene_update_pre.remove(populate_coll)
    scene.coll.clear()
    for identifier, name, description in enum_items:
        scene.coll.add().name = name

def register():
    bpy.utils.register_module(__name__)

    bpy.types.Scene.coll = bpy.props.CollectionProperty(
        type=bpy.types.PropertyGroup
    )

    bpy.types.Scene.coll_string = bpy.props.StringProperty()

    # Hack for testing
    bpy.app.handlers.scene_update_pre.append(populate_coll)


def unregister():
    bpy.utils.unregister_module(__name__)
    del bpy.types.Scene.coll
    del bpy.types.Scene.coll_string


if __name__ == "__main__":
    register()

For limitations please read:
Is it possible to use bpy.props.PointerProperty to store a pointer to an object?

share|improve this answer

Building off of the answer by @CoDEmanX, here's a simple example:

import bpy    

class OBJECT_PT_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
        scene = context.scene               
        layout.prop_search(scene, "theChosenObject", scene, "objects")


def register():
    bpy.utils.register_module(__name__)
    bpy.types.Scene.theChosenObject = bpy.props.StringProperty()


def unregister():
    bpy.utils.unregister_module(__name__)
    del bpy.types.Object.theChosenObject


if __name__ == "__main__":
    register()

which gives:

enter image description here

How script works

The prop_search command lets the user choose one item from a bpy "collection" (in this case, the collection context.scene.objects) and saves the name of that item into a string (the string context.scene.theChosenObject).

If you need to use the object in a different part of script. Use

scene = context.scene
obj = scene.objects[scene.theChosenObject]

By the way, if you had wanted a "Materials Selection Box", you could have used

layout.prop_search(scene, "theChosenMaterial", bpy.data, "materials")

and similarly for textures, meshes, or any other bpy collection.

Limitations

We are only saving the name of the object (for example, scene.theChosenObject could be 'Cube'). If the user changes the name of the object, scene.theChosenObject will not change and you will not be able to use it to reference the object anymore.

See here for more on this problem.

share|improve this answer
    
Shouldn't the second code box say scene.object[scene.theChosenObject] rather than scene.object(scene.theChosenObject)? –  Anonymouse Mar 23 at 15:15
    
@Anonymouse, thanks! I fixed it. –  Garrett Mar 23 at 20:34

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.