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:

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:

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:

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.
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.
scene.object[scene.theChosenObject] rather than scene.object(scene.theChosenObject)?
– linuxhackerman
Mar 23 '14 at 15:15
unregister should del property from the Scene, not from the Object? i.e del bpy.types.Scene.theChosenObject
– Max Yari
Jun 17 '19 at 16:30
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?
Here is an updated answer built on previously accepted answer.
Since 2.79, you can use bpy.props.PointerProperty to store references to blender data blocks.
You can then use prop instead of prop_search for selection box. prop_search is still useful if you want to select from a specific collection.
This solves the problem of modifying the object ( for example if you rename the object, the property will be updated). Also, deleting the object will not delete its data as, long as it is referenced somewhere. After all its references are removed, it gets deleted on file reload.
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
layout.prop(context.scene, "theChosenObject")
def register():
bpy.utils.register_module(name)
bpy.types.Scene.theChosenObject = PointerProperty(type=bpy.types.Object)
def unregister():
bpy.utils.unregister_module(name)
del bpy.types.Object.theChosenObject
if name == "main":
register()