1
$\begingroup$

How to set a default value for bpy.props.CollectionProperty?

Let's use the example in the documentation for an answer.

I tried to set the default value in the register function, but neither bpy.data nor bpy.context is available at that moment.

$\endgroup$
  • $\begingroup$ There is no default for a collection. By default the collection is empty when first defined. $\endgroup$ – batFINGER Sep 26 '18 at 16:07
  • $\begingroup$ Maybe there is a walk-around. I tried to set the default value in the register function, but neither bpy.data nor bpy.context is available at that moment. $\endgroup$ – vvoovv Sep 26 '18 at 17:06
  • $\begingroup$ Can you add to question what you want the default to be? From comment sounds like you want to add a default item on creation. One trick is to add a handler during rego that runs until one "default" item is added, then removes itself (the handler). $\endgroup$ – batFINGER Sep 27 '18 at 12:06
  • $\begingroup$ @batFINGER I've added a solution that worked for me as the answer $\endgroup$ – vvoovv Sep 27 '18 at 23:45
0
$\begingroup$

The idea is to use application handlers to set the default value for bpy.props.CollectionProperty:

Here is the code:

import bpy
from bpy.app.handlers import persistent

class MyCollectionItem(bpy.types.PropertyGroup):
    name = bpy.props.StringProperty(name="Name", default="Unknown")
    value = bpy.props.StringProperty(name="Value", default="Unknown")

def setDefaultCollectionValue():
    myCollection = bpy.context.scene.myCollection
    # set default value if <myCollection> is empty
    if not myCollection:
        collectionItem = myCollection.add()
        collectionItem.name = "Name 1"
        collectionItem.value = "Value 1"
        collectionItem = myCollection.add()
        collectionItem.name = "Name 2"
        collectionItem.value = "Value 2"

# This handler is needed to set the default value for <bpy.context.scene.myCollection>
# right after the addon registration via register()
def onRegister(scene):
    setDefaultCollectionValue()
    # the handler isn't needed anymore, so remove it
    bpy.app.handlers.scene_update_post.remove(onRegister)

# This handler is needed to set the default value for <bpy.context.scene.myCollection>
# after any of the following events:
# - opening Blender
# - reloading the start-up file via the keys Ctrl N
# - opening any Blender file
@persistent
def onFileLoaded(scene):
    addDefaultLevels()

def register():
    bpy.utils.register_class(MyCollectionItem)
    bpy.types.Scene.myCollection = bpy.props.CollectionProperty(type=MyCollectionItem)
    # adding handlers defined above in the code
    bpy.app.handlers.scene_update_post.append(onRegister)
    bpy.app.handlers.load_post.append(onFileLoaded)

def unregister():
    bpy.utils.unregister_class(MyCollectionItem)
    del bpy.types.Scene.myCollection
    bpy.app.handlers.load_post.remove(onFileLoaded)

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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.