Dropdown code no longer working in 2.93

This code worked in previous version of Blender, but now the dropdown appears without the items loaded. Does anyone know why?

Run it from the ‘Text Editor’.

import bpy


class LayoutDemoPanel(bpy.types.Panel):
    """Creates a Panel in the scene context of the properties editor"""
    bl_label = "Layout Demo"
    bl_idname = "SCENE_PT_layout"
    bl_space_type = 'PROPERTIES'
    bl_region_type = 'WINDOW'
    bl_context = "scene"

    def draw(self, context):
        layout = self.layout
        scene = context.scene
        # Create a simple row.
        layout.label(text=" Simple Row:")
        row = layout.row()
        row.operator_menu_enum("object.select_object", "select_objects", text = "Select object")
        

class WriteSelectObject(bpy.types.Operator):
    bl_idname = "object.select_object"
    bl_label = "Write Triangle Labels"

    def avail_objects(self,context):
        items = [(str(i),x.name,x.name) for i,x in enumerate(bpy.data.objects)]
        print(items)
        return items
    select_objects = bpy.props.EnumProperty(items = avail_objects, name = "Available Objects")

    @classmethod
    def poll(cls, context):
        return context.mode == 'OBJECT'
    
    def execute(self,context):
        #example behaviour, int(self.select_objects)] gives you the index of the selected           object
        bpy.ops.object.select_all(action="DESELECT")
        bpy.data.objects[int(self.select_objects)].select = True
        return {'FINISHED'}
    
def register():
    bpy.utils.register_class(LayoutDemoPanel)


def unregister():
    bpy.utils.unregister_class(LayoutDemoPanel)


if __name__ == "__main__":
    register()

The API has changed quite a bit since 2.79, so now you need to define properties like this:

my_prop: EnumProperty()

Rather than:

my_prop = EnumProperty()

I don’t see where in the code to make that change to make it work.

In your case, just change:

select_objects = bpy.props.EnumProperty(items = avail_objects, name = "Available Objects")

to:

select_objects: bpy.props.EnumProperty(items = avail_objects, name = "Available Objects")

Thanks for the help. There were other problems also though.

I updated the code to work from 2.83 to 2.93 for anyone else having a problem, but this issue is a more recent change. Using '=" or ‘:’ works fine on 2.83 to 2.92, but you have to use ‘:’ with 2.93.
Is this a Python change or a Blender change?

Here is the updated code:

import bpy




#-----Blender version compatibility.


def set_object_select_state(obj, state = True):
    if bpy.app.version < (2, 80):
        obj.select = state
    else:
        obj.select_set(state = state)

     
# This updates the class properties to annotation format for 2.8+.   
def make_annotations(cls):
    """Converts class fields to annotations if running with Blender 2.8"""
    if bpy.app.version < (2, 80):
        return cls
    bl_props = {k: v for k, v in cls.__dict__.items() if isinstance(v, tuple)}
    if bl_props:
        if '__annotations__' not in cls.__dict__:
            setattr(cls, '__annotations__', {})
        annotations = cls.__dict__['__annotations__']
        for k, v in bl_props.items():
            annotations[k] = v
            delattr(cls, k)
    return cls




#-----End Blender version compatibility




class Dropdown_PT_DemoPanel(bpy.types.Panel):
    """Creates a Panel in the scene context of the properties editor"""
    bl_label = "Layout Demo"
    bl_idname = "SCENE_PT_layout"
    bl_space_type = 'PROPERTIES'
    bl_region_type = 'WINDOW'
    bl_context = "scene"

    def draw(self, context):
        layout = self.layout
        scene = context.scene
        # Create a simple row.
        layout.label(text=" Simple Row:")
        row = layout.row()
        row.operator_menu_enum("object.select_object", "select_objects", text = "Select object")
        

class Dropdown_OT_SelectObject(bpy.types.Operator):
    bl_idname = "object.select_object"
    bl_label = "Write Triangle Labels"

    def avail_objects(self,context):
        items = [(str(i),x.name,x.name) for i,x in enumerate(bpy.data.objects)]
        #print(items)
        return items
    
    
    # Blender 2.92 and below can use '=' like this
    #select_objects = bpy.props.EnumProperty(items = avail_objects, name = "Available Objects")
    
    # 2.93+    
    select_objects : bpy.props.EnumProperty(items = avail_objects, name = "Available Objects")
    

    @classmethod
    def poll(cls, context):
        return context.mode == 'OBJECT'
    
    def execute(self,context):
        #example behaviour, int(self.select_objects)] gives you the index of the selected object
        obj = bpy.data.objects[int(self.select_objects)]
        #print(obj.select_get())
        
        bpy.ops.object.select_all(action="DESELECT")
        
        set_object_select_state(obj, state = True)
        print('Selected:', obj)
        
        return {'FINISHED'}



classes = (
    Dropdown_PT_DemoPanel,
    Dropdown_OT_SelectObject,
)

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


def unregister():
    for cls in reversed(classes):
        cls = make_annotations(cls)
        bpy.utils.unregister_class(cls)


if __name__ == "__main__":
    register()


1 Like

I’d like to hear the answer to this also.

Is this solved or not?

In Blender 2.93 Python was upgraded to version 3.9.1.