3
$\begingroup$

How to change an enum value to previous and next using operators?

enter image description here

import bpy


class PrevObject(bpy.types.Operator):
    bl_label = 'Previous'
    bl_idname = 'object.prev'
    
    def execute(self, context):
        return {'FINISHED'}


class NextObject(bpy.types.Operator):
    bl_label = 'Next'
    bl_idname = 'object.next'
    
    def execute(self, context):
        return {'FINISHED'}
    
    

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 = 'VIEW_3D'
    bl_region_type = 'UI'
    bl_category = "Object"

    def draw(self, context):
        layout = self.layout

        row = layout.row(align=True)
        row.operator('object.prev', text='', icon='TRIA_LEFT')
        row.prop(context.scene, 'enum', text='')
        row.operator('object.next', text='', icon='TRIA_RIGHT')
        

classes = (
    PrevObject,
    NextObject,
    HelloWorldPanel
)


def register():
    for cls in classes:
        bpy.utils.register_class(cls)
        
    def object_enum(self, context):
        return (
            (object.name, object.name, '', 'OBJECT_DATA', index)
            for index, object in enumerate(bpy.data.objects)
            if object.type == 'MESH'
        )

    bpy.types.Scene.enum = bpy.props.EnumProperty(items=object_enum)


def unregister():
    for cls in classes:
        bpy.utils.unregister_class(cls)
        
    del bpy.types.Scene.enum


if __name__ == "__main__":
    register()
$\endgroup$

1 Answer 1

2
$\begingroup$

This question feels like you're trying to shoehorn enum props into something they're not designed for, but to each their own.

Two things first : You have a typo in your panel draw, the object.prev operator is called twice.

And you need to use a permanent handle on your dynamic enum items otherwise you'll run into bugs down the line, especially with non-latin characters. See Is there a workaround for the known bug in dynamic EnumProperty?

Here's my proposal

import bpy


class PrevObject(bpy.types.Operator):
    bl_label = 'Previous'
    bl_idname = 'object.prev'
    
    def execute(self, context):
        object_enum_items = object_enum.items
        enum_index = [o[0] for o in object_enum_items].index(context.scene.enum)
        previous_index = enum_index - 1 if enum_index > 0 else len(object_enum_items) - 1
        context.scene.enum = object_enum_items[previous_index][0]
        return {'FINISHED'}


class NextObject(bpy.types.Operator):
    bl_label = 'Next'
    bl_idname = 'object.next'
    
    def execute(self, context):
        object_enum_items = object_enum.items
        enum_index = [o[0] for o in object_enum_items].index(context.scene.enum)
        next_index = enum_index + 1 if enum_index < len(object_enum_items) - 1 else 0
        context.scene.enum = object_enum_items[next_index][0]
        return {'FINISHED'}
    
    

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 = 'VIEW_3D'
    bl_region_type = 'UI'
    bl_category = "Object"

    def draw(self, context):
        layout = self.layout

        row = layout.row(align=True)
        row.operator('object.prev', text='', icon='TRIA_LEFT')
        row.prop(context.scene, 'enum', text='')
        row.operator('object.next', text='', icon='TRIA_RIGHT')
        

classes = (
    PrevObject,
    NextObject,
    HelloWorldPanel
)


def object_enum(self, context):
    object_enum.items = [
        (object.name, object.name, '', 'OBJECT_DATA', index)
        for index, object in enumerate(bpy.data.objects)
        if object.type == 'MESH'
    ]
    return object_enum.items

object_enum.items = []

def register():
    for cls in classes:
        bpy.utils.register_class(cls)
    bpy.types.Scene.enum = bpy.props.EnumProperty(items=object_enum)


if __name__ == "__main__":
    register()

By the way thank you for providing a fully working code snippet, that's way easier to use as a basis to help you !

$\endgroup$
2
  • $\begingroup$ not sure if it's still an issue but when I posted a similar answer blenderartists.org/t/increment-value-of-an-enumproperty/1288343/… " tonton" found an additional issue requiring initializing the enum property. $\endgroup$
    – Ratt
    Aug 18, 2023 at 23:06
  • $\begingroup$ @Ratt Hmm not sure, I tend to only access custom properties dictionary when they're defined using the UI, not via code. Might be a related to that. Thanks for the info ! Cheers $\endgroup$
    – Gorgious
    Aug 19, 2023 at 16:59

You must log in to answer this question.

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