3
$\begingroup$

I have a simple operator which creates an empty object and immediately prints out the object's name:

import bpy

class createEmpty(bpy.types.Operator):
    """Create an empty object"""
    bl_idname = 'make.empty'
    bl_label = 'Create an empty object'

    def execute(self, context):
        bpy.ops.object.empty_add(type='PLAIN_AXES')
        print(bpy.context.object.name)
        return {'FINISHED'}

class createEmptyPanel(bpy.types.Panel):
    bl_idname = 'create_empty_panel'
    bl_label = 'create empty object'
    bl_space_type = 'PROPERTIES'
    bl_region_type = 'WINDOW'
    bl_context = 'object'

    def draw(self, context):
        layout = self.layout
        row = layout.row()
        row.operator('make.empty')

bpy.utils.register_class(createEmpty)
bpy.utils.register_class(createEmptyPanel)

When I run this from the console, it creates an empty object and prints its name, 'Empty'. However, when I click the button in the UI, it creates an empty object, but prints the name of the object that was selected, in my case 'Cube'.

Why is this? Is there a better way to select the object I just created, other than bpy.context.object?

$\endgroup$
1

1 Answer 1

4
$\begingroup$

The simplest solution is to use active_object instead:

def execute(self, context):
    bpy.ops.object.empty_add(type='PLAIN_AXES')
    print(bpy.context.active_object.name)
    return {'FINISHED'}

Blender doesn't switch the bpy.context.object until after the createEmpty operator has completed, hence the Cube's name was being printed. Your operator is invoked from the createEmptyPanel which has bl_context = 'object', I suspect this has built in blocking of bpy.context.object changes.

Avoid this behaviour by using the lower level bpy.data.objects.new to make the empty. Change the execute function to avoid using bpy.ops.object.empty_add(), like:

import bpy

class createEmpty(bpy.types.Operator):
    """Create an empty object"""
    bl_idname = 'make.empty'
    bl_label = 'Create an empty object'

    def execute(self, context):
        # bpy.ops.object.empty_add(type='PLAIN_AXES')
        scene = context.scene
        objects = bpy.data.objects
        mt = objects.new("empty_name", None)
        mt.location = (0, 2, 1)
        mt.empty_draw_size = 2
        mt.empty_draw_type = 'PLAIN_AXES'
        scene.objects.link(mt)
        scene.update()
        print(mt.name)
        return {'FINISHED'}

class createEmptyPanel(bpy.types.Panel):
    bl_idname = 'create_empty_panel'
    bl_label = 'create empty object'
    bl_space_type = 'PROPERTIES'
    bl_region_type = 'WINDOW'
    bl_context = 'object'

    def draw(self, context):
        layout = self.layout
        row = layout.row()
        row.operator('make.empty')

bpy.utils.register_class(createEmpty)
bpy.utils.register_class(createEmptyPanel)

It's a bit more verbose, but it does immediately give you a reference to the new empty.

$\endgroup$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .