Getting a PointerProperty to work

Hello Community,

I am trying to learn the Python API and decided to create a lightlister (list all lights and show important properties, useful for lighting).
Sounded easy but I am quite stuck at managing visibility now.
Since a lighting artist usually just wants to turn off a light in viewport AND render, I decided to create an operator that just sets both variables with one button.
For that I the operator needs to know which light to control. No problem, just use a PointerProperty referencing the light…
Well I can’t get that to work. The property just isn’t there. Creating a BoolProperty works, but only if it gets created before the PointerProperty.
I am sure I am missing something super obvious here.
I am thankful for any help.
Also please point out if I am just trying to do things the wrong way.

Edit: Using 2.81a and Linux

Here’s the code


bl_info = {
    "name": "Lightlister",
    "author" : "Christoph Lendenfeld",
    "blender": (2, 81, 0),
    "category": "User",
}


import bpy

from bpy.props import (StringProperty,
                       BoolProperty,
                       IntProperty,
                       FloatProperty,
                       FloatVectorProperty,
                       EnumProperty,
                       PointerProperty,
                       )



class OBJECT_OT_DisableLight(bpy.types.Operator):
    bl_label = 'Disable Light'
    bl_idname = 'object.cl_disable_light'
    bl_options = {'REGISTER', 'UNDO'}

    # inverting the order of these properties makes it so my_bool disappears
    my_bool: bpy.props.BoolProperty(name="Toggle Option")
    light: bpy.props.PointerProperty(name = 'Light', type = bpy.types.Object)

    def execute(self, context):
        print (self.light)
        print (self.my_bool)
        return {'FINISHED'}



class Lightlister(bpy.types.Panel):
    """List Lights and expose attributes"""
    bl_label = "Lights"
    bl_idname = "LIGHTLISTER_PT_lightlisterPanel"
    bl_space_type = "VIEW_3D"   
    bl_region_type = "UI"
    bl_category = "Lightlister"

    @classmethod
    def poll(self,context):
        return context.object is not None

    def draw(self, context):
        layout = self.layout
        scene = context.scene
        for obj in bpy.data.objects:
            if obj.type != 'LIGHT': continue
            row = layout.row()
            row.prop(obj, 'name', text='')
            hideButton = row.operator('object.cl_disable_light', icon='HIDE_OFF', text='')
            hideButton.my_bool = True
            # script fails here
            hideButton.light = obj
            row.prop(obj.data, 'energy')
            row.prop(obj.data, 'color', text='')
            
        layout.separator()



classes = (
    OBJECT_OT_DisableLight,
    Lightlister
)

def register():
    for cls in classes:
        bpy.utils.register_class(cls)


def unregister():
    for cls in classes:
        bpy.utils.unregister_class(cls)

If I remember correctly, PointerProperties can’t be used in operators.
You could identify the light by name instead (use a StringProperty).

1 Like

thank you for the info.
Yeah i got it working using a StringProperty. Since draw() gets called so often i don’t need to worry about renamed objects anyway.

Do you know where it would say that the PointerProperty doesn’t work inside an operator. It didn’t throw an error and in the future i’d like to know where to check for such things.

Unfortunately I don’t know, I just remembered vaguely. I checked the Blender Python API docs, but it’s not mentioned there.

Try with this method. It works for me.