1
$\begingroup$

The questions keep coming, I know. I cannot find this simple answer anywhere. It may be because I'm not sure exactly how to phrase it in searches.

Is it possible to declare a variable of a custom type that is derived from bpy.types.PropertyGroup?

I have a situation where I create controls for the active object. But I would like to show these controls in a disabled state when there is no active object (or any object at all). So my (possibly terrible) idea is to declare a local variable of the property group used by objects and use the data in this temporary property group to draw the buttons and controls. I know I can just skip drawing the associated controls, but I don't like how disruptive it is to have the panel contents shift around when it happens.

Here is an example of what I mean:

class MyClass(bpy.types.PropertyGroup):
    Var : BoolProperty(
        name = "Stuff",
        description = "my stuff",
        default=False
        )

def draw_panel():

    if active_object:
        draw_buttons(active_object.MyProperties, disabled=false)
    else:
        temp_props = MyClass()
        draw_buttons(temp_props, disabled=true)

So the controls would be associated with a temporary property object. However, the code temp_props = MyClass() does not work. It appears that bpy_struct requires some type of "constructor parameter" (I'm not sure what these are called in python)?

If there is a better way to handle this, please feel free to slap me out of this idea. And in either case, how would one go about declaring a class derived from a property group or bpy_struct locally within a function? Is it even possible? I can't seem to find anything in the API docs about initializing one of these objects on our own.

$\endgroup$
1
$\begingroup$

One simple way to accomplish this is to set up a PointerProperty on the scene to store these values:

def register():
    bpy.utils.register_class(MyClass)
    bpy.types.Scene.temp_props = PointerProperty(type=MyClass)

Now you can reference the properties in your draw_buttons call with bpy.context.scene.temp_props:

def draw_panel():

    if active_object:
        draw_buttons(active_object.MyProperties, disabled=False)
    else:
        temp_props = bpy.context.scene.temp_props
        draw_buttons(temp_props, disabled=True)

You can also store the PointerProperty to many other ID structs from bpy.types (e.g. Object, World, ViewLayer, etc.).

(related: How do I register 'Scene' properties with Python in 2.8?)

$\endgroup$
  • $\begingroup$ Thank you for pointing this out. Can anyone help me understand why it works to add my custom property groups to blender objects (objects, scene), but I get errors when I try to add them to my own structures (eg, Panel.TempObjectProperties)? The environment complains when I try to use a property inside prop_enum() when the property group is owned by the panel. It reports "Function.data expected a AnyType type, not tuple". Is Blender doing something additional to initialize these behind the scenes? Or are property groups exclusively designed for object association? $\endgroup$ – Robert Sep 12 at 15:57

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.