3
$\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 Answer 1

3
$\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$
1
  • 1
    $\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, 2019 at 15:57

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .