1
$\begingroup$

I created a search popup panel with a enum-property which holds a list of colors. The list gets populated with the "fill_item_list()" function and that works quite well. The problem is that this list only gets updated once in the beginning. Is there a way to make it update again e.g. in the invoke-function?

Here is the class:

class MYCAT_OT_search_popup(bpy.types.Operator):
bl_idname = "object.search_popup"
bl_label = "Color Search"
bl_property = "my_enum"

my_enum: bpy.props.EnumProperty(items = fill_item_list(), name='New Name', default=None)


def execute(self, context):
    context.scene.PM_MatProp.color_enum = self.my_enum
    return {'FINISHED'}

def invoke(self, context, event):
    wm = context.window_manager
    wm.invoke_search_popup(self)
    return {'FINISHED'}


class ColorButton_Operator(bpy.types.Operator):

    bl_idname = 'opr.color_button_operator'
    bl_label = 'Color Button'


    def execute(self, context):
        params = (
            context.scene.my_enum
        )

        return {'FINISHED'}

Thanks in advance.

$\endgroup$

1 Answer 1

1
$\begingroup$

fill_item_list() will asign the result of the function to items, which is valid but will yield a static list.

You can't update a static enum item list once it has been setup at register.

If you want a dynamic item list, you must assign the function, not the result of the function. eg items = fill_item_list where fill_item_list takes two inputs : self, and context, which are automatically provided when the items are feteched when the enum field is displayed.

So that would look like that

def fill_item_list(self, context):
    if context.my_condition:
        fill_item_list.items = ("item1",) * 3
    else:
        fill_item_list.items = ("item2",) * 3
    return fill_item_list.items
fill_item_list.items = []

and in your operator

my_enum: bpy.props.EnumProperty(items=fill_item_list, name='New Name', default=None)

You do not have to use the default parameters. Using a lambda expression you can keep your function as is.

def fill_item_list():
    if my_condition:
        fill_item_list.items = ("item1",) * 3
    else:
        fill_item_list.items = ("item2",) * 3
    return fill_item_list.items
fill_item_list.items = []

and then

my_enum: bpy.props.EnumProperty(items=lambda self, context: fill_item_list(), name='New Name', default=None)

More information in the docs : https://docs.blender.org/api/current/bpy.props.html#bpy.props.EnumProperty

Also be aware of the dynamic enum items bug

Is there a workaround for the known bug in dynamic EnumProperty?

$\endgroup$
3
  • $\begingroup$ Thank you very much, Gorgious. I didn't know that just the brackets would make the list static. That seemed to work and updates the list during runtime. However now I have the problem that some entries are displayed as cryptic signs for names that have "umlaute" or special signs in it. Also it crashes Blender when I type something in the search field. Maybe a text encrypting/encoding issue or something. But thanks for the help so far! $\endgroup$ Aug 3, 2023 at 10:55
  • 1
    $\begingroup$ Glad it helped ! Please refer to the last link in my answer and the warning in the documentation :) dynamic enum items must be stored in a permanent variable. $\endgroup$
    – Gorgious
    Aug 5, 2023 at 6:54
  • 1
    $\begingroup$ @Braindrain85 I've updated the answer accordingly $\endgroup$
    – Gorgious
    Aug 5, 2023 at 6:56

You must log in to answer this question.

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