3
$\begingroup$

I'm working on an addon where I'd like to be able to select a collection from a drop down list.

The Freestyle options have a way to do it, and it looks like this:

enter image description here

I used the developer tools to look and see what the Python code is like for the UI there, and it's something like this:

layout.row().prop(lineset, "collection", text="Line Set Collection")

I'm pretty new to building UI in Blender/Python, but obviously copying and pasting this into the draw function of the Panel in my addon didn't do what it needed to do (the lineset of course is not defined for my addon). But what do I need to do to be able to get a similar drop down box where I can select a collection?

Thanks!

$\endgroup$
1
  • $\begingroup$ This sort of thing is usually done with a UIList. This tutroial is a good starting point for understanding UILists. [This answer](blender.stackexchange.com/a/249940/42221} has a sample code. You need to adapt it to fill the List with Collection names but it's not far from what you need. By the way, the UIList in the Freestyle code starts at line 122 of properties_freestyle.py in 3.1.2 $\endgroup$ Apr 6, 2022 at 23:39

1 Answer 1

7
$\begingroup$

You can use a bpy.props.PointerProperty linking to a bpy.types.Collection.

import bpy


class HelloWorldPanel(bpy.types.Panel):
    bl_label = "Hello World Panel"
    bl_idname = "OBJECT_PT_hello"
    bl_space_type = 'PROPERTIES'
    bl_region_type = 'WINDOW'
    bl_context = "scene"

    def draw(self, context):
        self.layout.prop(context.scene, "my_collection")


def register():
    bpy.types.Scene.my_collection = bpy.props.PointerProperty(type=bpy.types.Collection)
    bpy.utils.register_class(HelloWorldPanel)


if __name__ == "__main__":
    register()

Result :

enter image description here

You can also use the poll parameter to add a custom filter function to the displayed collections. The two parameters self and col will point to the current scene and the collection entry. The entry will be dynamically shown or hidden depending on the return value of the function.

e.g. Show only collections which name ends with 1

def custom_poll(self, col):
    return col.name.endswith("1")

Then replace my_collection definition with

bpy.types.Scene.my_collection = bpy.props.PointerProperty(
    type=bpy.types.Collection, 
    poll=custom_poll)   

enter image description here

$\endgroup$
2
  • $\begingroup$ Awesome, very impressive! So I guess the layout.prop will adjust the display depending on the type of data that the property is pointing to? Way cool! In the unregister() function, should I go ahead and delete it as well using del bpy.types.Scene.my_collection ? Thanks a ton! $\endgroup$ Apr 7, 2022 at 23:06
  • 1
    $\begingroup$ @AnsonSavage yup exactly ! Happy to help :) $\endgroup$
    – Gorgious
    Apr 8, 2022 at 5:56

You must log in to answer this question.

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