EnumType with 500+ items. what to do?

Hi, I’m new to blender scripting, so bear with me (and my english).

I’m trying to code an interface popup dialog which has an EnumProperty to it. That works just fine. Now the problem is that my EnumProperty has several hundred items, most of which can not be seen on screen. Scrolling doesn’t work. I would need something like the file selector to select the items of the list. Can that be done? Is it even clear what I want to do?

With that many enums, you might try using a CollectionProperty to hold your items, and display it with a template_list.


class thing(bpy.types.PropertyGroup):
    name = bpy.props.StringProperty()

…for the property definitions

define a UIList class for the template_list to use:


class thinglist(bpy.types.UIList):
    bl_idname = "listthings"
    def draw_item(self, context, layout, data, item, icon, active_data, active_propname):
        layout.label(item.name)

lets pretend we attached the things property to the scene type ( in registration):


bpy.types.Scene.things = bpy.props.CollectionProperty(type=thing)
bpy.types.Scene.active_thing = bpy.props.IntProperty(default=-1,min=-1)


and to draw it:


layout.template_list("listthings","",context.scene,"things",context.scene,"active_thing")

…just a thought

Thanks for the input. Seems to be exactly what I need…

you could use a search popup

import bpy

class SimpleOperator(bpy.types.Operator):
    """Tooltip"""
    bl_idname = "object.simple_operator"
    bl_label = "Simple Object Operator"
    bl_options = {'REGISTER', 'UNDO'}
    bl_property = "enumprop"
    
    def item_cb(self, context):
        return [(mat.name, mat.name, '') for mat in self.mats]
    
    mats = bpy.props.CollectionProperty(type=bpy.types.PropertyGroup)
    enumprop = bpy.props.EnumProperty(items=item_cb)#(('1','One',''),('2','Two','')))

    @classmethod
    def poll(cls, context):
        return (context.active_object is not None and
                context.active_object.type == 'MESH')    

    def execute(self, context):
        self.report({'INFO'}, self.enumprop)
        return {'FINISHED'}

    def invoke(self, context, event):
        self.mats.clear()
        for i in range(1, 7):
            self.mats.add().name = "Material %i" % i
        context.window_manager.invoke_search_popup(self)
        return {'FINISHED'}


def register():
    bpy.utils.register_class(SimpleOperator)


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


if __name__ == "__main__":
    register()

    # test call
    bpy.ops.object.simple_operator('INVOKE_DEFAULT')


Ok, I got it working in a panel. However, when in a popup dialog, the display just hangs. No scrolling possible. Am I doing something wrong here or is it a bug? Here 's the code:

import bpy
import xml.etree.ElementTree as etree


class thing(bpy.types.PropertyGroup):
    name = bpy.props.StringProperty(name = "Item", default = "test")
    
class thinglist(bpy.types.UIList):
    bl_idname = "listthings"
    def draw_item(self, context, layout, data, item, icon, active_data, active_propname):
        layout.label(item.name)
        
class DialogOperator(bpy.types.Operator):
    """Creates a popup dialog"""
    bl_label = "My Panel"
    bl_idname = "object.dialog_operator"


    def draw(self, context):
        layout = self.layout
        layout.template_list("listthings", "", context.scene, "things", context.scene, "active_thing")
        layout.template_list("listthings", "compact", context.scene, "things",
                             context.scene, "active_thing", type='COMPACT')


    def execute(self, context):
        print(context.scene.active_thing)
        return {'FINISHED'}
    
    def invoke(self,context, event):
        return context.window_manager.invoke_props_dialog(self,width = 600, height = 400)




def register():
    bpy.utils.register_class(DialogOperator)
    bpy.utils.register_class(thing)
    bpy.utils.register_class(thinglist)
    bpy.types.Scene.things = bpy.props.CollectionProperty(type = thing)
    bpy.types.Scene.active_thing = bpy.props.IntProperty(default = 0, min = 0)




def unregister():
    bpy.utils.unregister_class(DialogOperator)
    bpy.utils.unregister_class(thing)
    bpy.utils.unregister_class(thinglist)
    del bpy.types.Scene.things
    del bpy.types.Scene.active_thing


if __name__ == "__main__":
    register()
    modeldef = "D:\\example.xml"
    tree = etree.parse(modeldef)
    root = tree.getroot()
    
    bpy.context.scene.things.clear()
    for anim in root:
        if anim.tag == 'Animation':
            item = bpy.context.scene.things.add()
            item.name = anim.attrib['name']


    # test call
    bpy.ops.object.dialog_operator('INVOKE_DEFAULT')

Thanks again for your valuable input, to both of you. I will now investigate CoDEmanX’s suggestion.