Edit for brevity and clarity. The short short version is that I can use a PointerProperty and set it via a UI panel, but actually trying to set the value in a python operator suddenly makes the UI panel reading the value throw errors.
I’ve searched around and found a couple of references to this, but I’ll be damned if I can make heads or tails of them, and most are many years outdated anyway, so I figure I should ask here.
In a personal addon I am working on, I’m using a PointerProperty to specify a target for an operation, instead of just a text field with the name. Among other things, this lets me use the eyedropper function to select an object.
Setting values / selecting objects in the UI works fine, both with the dropdown list, and the eyedropper. But when an operator changes the value (in this example, I have a button that sets the variable to point to the active object), suddenly row.prop() stops working.
Specifically, the code that displays the field produces the error:
rna_uiItemR: property not found: TestProps.propertyDisplayTarget
This despite the fact that other calls like
rna_uiItemR: property not found: TestProps.propertyDisplayTarget
work just fine.
Here is my code, stripped down to the bare minimum:
import bpy
class TestProps(bpy.types.PropertyGroup):
propertyDisplayTarget: bpy.props.PointerProperty(name = "Object", type = bpy.types.Object)
propertyDisplayUseActiveObject: bpy.props.BoolProperty(name = "Use Active")
class TEST_OT_setPropertyDisplayTargetToActive(bpy.types.Operator):
"""Set property display target object to active"""
bl_idname = "object.setpropertydisplaytargettoactive"
bl_label = "Set to active"
bl_context = "object"
@classmethod
def poll(cls, context):
if bpy.context.active_object:
return True
else:
return False
def execute(self, context):
TestProps.propertyDisplayTarget = bpy.context.active_object.id_data
print("#"*7, "set ", TestProps.propertyDisplayTarget)
return {'FINISHED'}
class TEST_PT_propertiesPanel(bpy.types.Panel):
"""Shows properties of specified object"""
bl_label = "Object/Bone Properties"
bl_idname = "SCENE_PT_properties"
bl_space_type = 'VIEW_3D'
bl_category = 'Testing'
bl_region_type = "UI"
@classmethod
def poll(cls, context):
return True
def draw(self, context):
layout = self.layout
scene = bpy.context.scene
row = layout.row()
row.label(text = "Test panel")
row = layout.row()
if scene.TestProps:
row = layout.row()
row.label(text = "Target name is " + scene.TestProps.propertyDisplayTarget.name)
row = layout.row()
row.prop(scene.TestProps, "propertyDisplayTarget")
row = layout.row()
row.operator('object.setpropertydisplaytargettoactive')
classes = (TestProps,
TEST_OT_setPropertyDisplayTargetToActive,
TEST_PT_propertiesPanel,
TestProps
)
def register():
from bpy.utils import register_class
for cls in classes:
register_class(cls)
bpy.types.Scene.TestProps = bpy.props.PointerProperty(type=TestProps)
def unregister():
from bpy.utils import unregister_class
for cls in reversed(classes):
unregister_class(cls)
del bpy.types.Scene.TestProps
if __name__ == "__main__":
register()
It works fine until I use the “set to active” button. Then it stops working and spams my console with the error stated above.
Also, I can still access the PointerProperty from the console just fine, it is ONLY the prop field in the UI panel that breaks.
Can anyone explain this to me? Thanks!
