4
$\begingroup$

I'm trying to create property groups dynamically to store a list. When I loop through property groups all I get is the objects like the output code block below. When really what I want is the test strings. At least the objects are actually created but I really need to access the string I'm hopefully setting on them. Please help. Been trying to work this out for days.

If the indents look off they are fine in my actual code.

class customPropertiesGroup(bpy.types.PropertyGroup):
  customString = bpy.props.StringProperty()

bpy.utils.register_class(customPropertiesGroup)

bpy.types.Scene.customLists : bpy.props.CollectionProperty(type=customPropertiesGroup) 

newCustomItem = bpy.context.scene.customLists.add()
newCustomItem.customString = "test1"
newCustomItem = bpy.context.scene.customLists.add()
newCustomItem.customString = "test2"  

# These retrieve the objects OK.
bpy.context.scene.customLists[0].customString
bpy.context.scene.customLists[1].customString
# This is out of range. Which is surely good because it means something is working. 
bpy.context.scene.customLists[2749].customString


count = 0
for customString in bpy.context.scene.customLists:
  count += 1
  print(count)
  print(customString)

OUTPUT. I get a list of these with the count number. Two different mem addresses of course.

 1
 <bpy_struct, customPropertiesGroup("") at 0x000002311A3FE908>
$\endgroup$

1 Answer 1

5
$\begingroup$

Your code has two problems :

  • You need to use an annotation (:) to define the StringProperty in the PropertyGroup class.
  • When you iterate over your customLists, you do not gain a direct access to your customString. It wouldn't make sense because the property group may have other properties. As a matter of fact, it has at least one other property, which is builtin, called name.

So you can replace your code with :

import bpy

class CustomPropertiesGroup(bpy.types.PropertyGroup):
  customString: bpy.props.StringProperty()

bpy.utils.register_class(CustomPropertiesGroup)

bpy.types.Scene.customLists: bpy.props.CollectionProperty(type=CustomPropertiesGroup) 

newCustomItem = bpy.context.scene.customLists.add()
newCustomItem.customString = "test1"
newCustomItem = bpy.context.scene.customLists.add()
newCustomItem.customString = "test2"  


for count, customPropertyGroup in enumerate(bpy.context.scene.customLists):
  print(count + 1)
  print(customPropertyGroup.customString)

BTW the python guidelines suggest to use snake_case instead of camelCase for naming variables and functions, and PascalCase for classes.

$\endgroup$
4
  • $\begingroup$ you were faster, deleted my identical answer $\endgroup$
    – relaxed
    Jan 19 at 8:32
  • $\begingroup$ @relaxed you should have let it be ! I personaly don't mind at all. I was surprised at first because using bpy.types.Scene.customLists : bpy.props.CollectionProperty(type=customPropertiesGroup) still works when I ran the script when it shouldn't ? Or maybe it's supported but will be deprecated in future versions ? would love to have your insight on the matter. $\endgroup$
    – Gorgious
    Jan 19 at 8:36
  • 1
    $\begingroup$ @ Gorgious It seems to be the other direction. It works in 2.93, but failed in 2.83. Interesting. I never stop learning.. $\endgroup$
    – relaxed
    Jan 19 at 8:51
  • $\begingroup$ Basically what worked for me is swapping : and = in the example in the obvious places in question. Thanks for the tips. I didn't really understand all that before but I knew there was some new convention. $\endgroup$ Jan 19 at 14:46

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.