I am dynamically adding a custom property to certain objects in a scene and I want to display that property in a panel. The custom property is a dictionary with keys that point to basic types, I only want to display some of the keys. Below is a simplified version of the workflow - the user selects an object, clicks a button and the property gets added, then I'd like the user to edit some of the data. Unfortunately I can't figure out how to get the panel to display/edit some of the values from the dictionary.
class myDynamicPropertyDict(dict):
def __init__(self):
self['userEditable'] = '<user-editable text>'
self['internalUse'] = '<non-user-editable stuff>'
class MYCOMPANY_OT_AddProperty(bpy.types.Operator):
bl_label = "Add Property"
bl_idname = "mycompany.addproperty"
def execute(self, context):
if context.active_object.get("myProp") is None:
context.active_object["myProp"] = myDynamicPropertyDict()
return {'FINISHED'}
class MYCOMPANY_PT_TestPanel(bpy.types.Panel):
bl_label="Test Panel"
bl_space_type = "VIEW_3D"
bl_region_type = "UI"
def draw(self, context):
layout=self.layout
layout.operator("mycompany.addproperty", text = "Add", icon="ADD")
if context.active_object and ("myProp" in context.active_object):
### Attempt #1 ###
### Results in this message:
# TypeError: UILayout.prop(): error with keyword argument "data" - Function.data expected a AnyType type, not IDPropertyGroup
#
# location: <unknown location>:-1
### layout.prop( data=context.active_object["myProp"], property='["userEditable"]')
### Attempt #2 ###
### Results in this message:
# rna_uiItemR: property not found: Object.["myProp"]["userEditable"]
### layout.prop( data=context.active_object, property='["myProp"]["userEditable"]')
### Attempt #3 ###
### Renders, but get a mouseover saying "This property is for internal use only and is disabled."
### layout.prop( data=context.active_object, property='["myProp"]')
layout.label(text="Dummy label to see something rendering")
def register():
bpy.utils.register_class(MYCOMPANY_OT_AddProperty)
bpy.utils.register_class(MYCOMPANY_PT_TestPanel)
def unregister():
bpy.utils.unregister_class(MYCOMPANY_PT_TestPanel)
bpy.utils.unregister_class(MYCOMPANY_OT_AddProperty)
if name == "main":
register()
```
bpy.propsproperties. see https://docs.blender.org/api/current/bpy.props.html for examples. Maybe this will help https://blender.stackexchange.com/a/176499/86891. tldr : you'll have to define blender specific properties to store your dictionary and a custom layout system to display it like you want – Gorgious Mar 29 '22 at 19:46json.loadsandjson.dumpsto store it in a regular string custom prop – Gorgious Mar 29 '22 at 19:50