3
$\begingroup$

I am trying to pass a collection as parameter of an operator, but I have following issue :

AttributeError: bpy_struct: attribute "collection" from OBJECT_OT_example_op" is read-only

Here is my example code :

import bpy

class Item(bpy.types.PropertyGroup):
    name = bpy.props.StringProperty(name="Name")

class ExamplePanel(bpy.types.Panel):
    bl_label = "ExamplePanel"
    bl_space_type = 'VIEW_3D'
    bl_region_type = 'TOOLS'
    bl_category = "Example"

    @classmethod
    def poll(self, context):
        return True

    def draw(self, context):
        layout = self.layout
        layout.operator("object.example_op", text="Test").collection = bpy.context.scene.collection

class ExampleOperator(bpy.types.Operator): 
    bl_idname = "object.example_op"
    bl_label = "Example Operator"
    bl_options = {'REGISTER'}   

    collection = bpy.props.CollectionProperty(type=Item)

    @classmethod
    def poll(self, context):
        return True

    def execute(self, context):
        for item in self.collection:
            print(item.name)
        return {'FINISHED'}

def register():
    bpy.utils.register_class(Item)
    bpy.types.Scene.collection = bpy.props.CollectionProperty(type=Item)

    it = bpy.context.scene.collection.add()
    it.name = "item1"
    it = bpy.context.scene.collection.add()
    it.name = "item2"   

    bpy.utils.register_class(ExampleOperator)
    bpy.utils.register_class(ExamplePanel)


if __name__ == "__main__":
    register()

Any suggestions ? Tried with PointerProperty, but don't know exactly how to use it, and got same error.

Thanks :)

$\endgroup$
  • $\begingroup$ Not sure how to pass collection prop to an operator in the layout. My suggestion is change for item in self.collection to for item in context.scene.collection ie use the scene collection in the operator. You can however use bpy.ops.object.example_op(coll=[{"name":"Goose"}, {"name":"Herman"}]) to pass the collection to the operator... coll=scene.collection will throw an error too. $\endgroup$ – batFINGER Mar 9 '16 at 16:52
  • $\begingroup$ Thanks for your answer. I can't use directly context.scene.collection in my case. Will work in this example, but my real case is more complicated, and is not a property of bpy.types.Scene. $\endgroup$ – Julien Mar 10 '16 at 7:23
2
$\begingroup$

Campbell give me an answer in Blender mailing list. Here is the proposed solution :

import bpy

class Item(bpy.types.PropertyGroup):
    name = bpy.props.StringProperty(name="Name")

class ExamplePanel(bpy.types.Panel):
    bl_label = "ExamplePanel"
    bl_space_type = 'VIEW_3D'
    bl_region_type = 'TOOLS'
    bl_category = "Example"

    @classmethod
    def poll(self, context):
        return True

    def draw(self, context):
        layout = self.layout
        op = layout.operator("object.example_op", text="Test")
        for src_item in bpy.context.scene.collection:
            dest_item = op.collection.add()
            dest_item.name = src_item.name


class ExampleOperator(bpy.types.Operator): 
    bl_idname = "object.example_op"
    bl_label = "Example Operator"
    bl_options = {'REGISTER'}   

    collection = bpy.props.CollectionProperty(type=Item)

    @classmethod
    def poll(self, context):
        return True

    def execute(self, context):
        for item in self.collection:
            print(item.name)
        return {'FINISHED'}

def register():
    bpy.utils.register_class(Item)
    bpy.types.Scene.collection = bpy.props.CollectionProperty(type=Item)

    it = bpy.context.scene.collection.add()
    it.name = "item1"
    it = bpy.context.scene.collection.add()
    it.name = "item2"   

    bpy.utils.register_class(ExampleOperator)
    bpy.utils.register_class(ExamplePanel)


if __name__ == "__main__":
    register()
$\endgroup$
  • $\begingroup$ This example should be in the official documentation. Great example. $\endgroup$ – satishgoda Jun 10 '17 at 8:13

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.