Trigger an action depending on the item selected in the dropdown menu

I’m trying to trigger an action depending on the each item in the dropdown menu but I cannot find the way to do it.

The script will create new buttons and each of them will have a dropdown with 3 options, one selects a cube, another one selects the light and the third one selects the camera. I get an error in the script when I click in any option:
image

Here is a screenshot of the script, just posted a stripped down version of the code that still works.
image

import bpy
from bpy.types import PropertyGroup, Operator
from bpy.types import Scene
from bpy.props import StringProperty, BoolProperty



def update_enum(self, context):
    print(self.my_enum)
    eval(self.my_enum)

class SceneItems(bpy.types.PropertyGroup):
    value : bpy.props.IntProperty()
    
    my_enum: bpy.props.EnumProperty(
        name= "Dropdown",
        description= "text",
        items= [('OP1', "Select Cube", "", "MESH_CUBE", 1),
                ('OP2', "Select Light", "", "OUTLINER_OB_LIGHT", 2 ),
                ('OP3', "Select Camera", "", "VIEW_CAMERA", 3)
        ],
        update=update_enum
    )

class SelectItems(bpy.types.Operator):
    bl_idname = "scene.select_cube_operator"
    bl_label = "Select Cube Button"
    
    def execute(self, context):
        selcube = context.scene.newbutton
        
        if selcube.context.scene.newbutton == 'OP1':
            bpy.data.objects["Cube"].select_set(True)
                    
        if selcube.context.scene.newbutton == 'OP2':
            bpy.data.objects["Light"].select_set(True)
            
        if selcube.context.scene.newbutton == 'OP3':
            bpy.data.objects["Camera"].select_set(True)           
            
        return {'FINISHED'}
    
class AddButtonOperator(bpy.types.Operator):
    bl_idname = "scene.add_button_operator"
    bl_label = "Add Button"

    def execute(self, context):
        id = len(context.scene.newbutton)
        new = context.scene.newbutton.add()
        new.name = str(id)
        new.value = id
        return {'FINISHED'}

class RemoveButtonOperator(bpy.types.Operator):
    bl_idname = "scene.remove_button_operator"
    bl_label = "Remove Button"

    id : bpy.props.IntProperty()

    def execute(self, context):
        bpy.context.scene.newbutton.remove(self.id)
        print("Pressed button ", self.id)
        return {'FINISHED'}

class FancyPanel(bpy.types.Panel):
    bl_label = "Fancy Panel"
    bl_space_type = 'VIEW_3D'
    bl_region_type = 'UI'

    def draw(self, context):
        self.layout.operator("scene.add_button_operator")
        
        for idx, item in enumerate(context.scene.newbutton):
                row = self.layout.row(align=True)

                row.prop(item, "my_enum", text="")
                row.operator("scene.remove_button_operator", text='', icon = "PANEL_CLOSE").id = idx

classes = (
    SceneItems,
    AddButtonOperator,
    FancyPanel,
    RemoveButtonOperator,
    SelectItems,
)

def register():
    for cls in classes:
        bpy.utils.register_class(cls)

    bpy.types.Scene.newbutton = bpy.props.CollectionProperty(type = SceneItems)


def unregister():
    for cls in classes:
        bpy.utils.unregister_class(cls)
       
if __name__ == "__main__":
    register()

Cheers.

You are getting an error because you are passing the enum item name to the eval function. When you set the enum to ‘OP1’ for example, the eval function receives the string ‘OP1’ to evaluate. It then looks for an object named ‘OP1’ but this doesn’t exist.

I’m not sure what the purpose of this line is for. Remove it and your appears to work as expected.

Thanks, you mean getting rid of this line?

eval(self.my_enum)

Yes, that’s the line that is giving you the error but the code you posted doesn’t show the buttons though so I’m assuming you stripped those out.

You probably want to change selcube.context.scene.newbutton == 'OP1': to selcube.context.scene.newbutton.my_emum == 'OP1': and I would suggest naming newbutton to something plural like ‘fancy_panel_buttons’ as the property represents a collection

1 Like

Thank you for your explanation, I’m understanding a little bit more :slight_smile:

Sadly the script is still not working, when I select from the dropdown menu for example: Select Cube, it should select automatically the cube but is not doing anything.

Yes that’s because it looks like you previously the selection to happen when the buttons were pressed.

If you want it to happen when the drop down is selected define the logic in the update_enum function

def update_enum(self, context):
    if self.my_enum == 'OP1':
        context.view_layer.objects["Cube"].select_set(True)
    elif self.my_enum == 'OP2':
        context.view_layer.objects["Light"].select_set(True)
    elif self.my_enum == 'OP3':
        context.view_layer.objects["Camera"].select_set(True)
1 Like

Awesome, thank you for your time on this, now I understand. the operations goes into the update and not into another operator.