3
$\begingroup$

I'm using Custom Properties (/ID properties) to store a dynamic list of properties I expose in a panel (cf dynamic PropertyGroup / Panel).

I can easily handle all of the property types I'm interested in. All except boolean properties. For some reason, Blender does not support ID properties of type bool.

I would like to emulate bool properties using an integer (for example).

My question is: how can I render a panel with a checkbox that will somehow change the value of that integer?

Thank you,

$\endgroup$
3

2 Answers 2

3
$\begingroup$

ID properties can't be displayed as checkboxes:

import bpy

def draw_func(self, context):
    layout = self.layout
    ob = context.object

    try:
        ob["myBool"]
    except (AttributeError, KeyError):
        layout.label('No ["myBool"] property.')
    else:
        layout.prop(ob, '["myBool"]', toggle=True, slider=False)

def register():
    bpy.types.OBJECT_PT_custom_props.prepend(draw_func)

def unregister():
    bpy.types.OBJECT_PT_custom_props.remove(draw_func)

if __name__ == "__main__":
    register()

They will always display as integer or floating point numbers, and also stored this way.

You need to use bpy.props.BoolProperty() for checkboxes.

$\endgroup$
4
  • $\begingroup$ I know that ID properties cannot be bool. That's why I want to emulate bool ID properties. But I need bool ID properties because only ID properties are exported in FBX and I need boolean values. $\endgroup$ Commented Aug 18, 2015 at 6:33
  • $\begingroup$ I guess you could simply change the FBX script to use a bpy.props property. Cast the value as needed. There's no difference between ID properties and bpy.props properties internally anyway. $\endgroup$
    – CodeManX
    Commented Aug 18, 2015 at 6:58
  • $\begingroup$ AFAIK it's a much more complicated process/implementation than just using the proxy method I describe in my answer. $\endgroup$ Commented Aug 18, 2015 at 7:15
  • $\begingroup$ Perhaps, but also a smaller overhead (because it would only cast on export). $\endgroup$
    – CodeManX
    Commented Aug 18, 2015 at 13:39
3
$\begingroup$

It's actually pretty easy to do:

1 - Create a proxy PropertyGroup that will represent your bool properties: that proxy should have just a "value" field of type BoolProperty. Also make sure the update function of that property will actually change the ID property:

class BoolPropertyProxy(bpy.types.PropertyGroup):
    value = BoolProperty(name="Value", update=bool_property_update)

def minko_script_bool_property_update(self, context):
    context.active_object[self.name] = self.value

bpy.utils.register_class(BoolPropertyProxy)
bpy.types.Object.bool_properties = bpy.props.CollectionProperty(type=BoolPropertyProxy)

2 - When creating your ID properties, if the property is a bool then create and store an additional BoolPropertyProxy:

obj['properties'] = props
for key, key_type in props.items():
    obj[key] = get_property_default_value(key)
    if key_type == 'bool':
        bool_prop = obj.bool_properties.add()
        bool_prop.name = key
        bool_prop.value = get_property_default_value(key)

3 - In the UI, if the property is typed as a bool, use the corresponding proxy instead:

for key, key_type in obj['properties']:
    if key_type == 'bool':
        for bool_prop in obj.bool_properties:
            if bool_prop.name == key:
                col.prop(bool_prop, 'value', text=key)
                break
    else:
        col.prop(obj, '["' + key + '"]', text=key)

The value is stilled stored as an integer, but it's displayed as a checkbox which is much more convenient. I guess the same "proxy" idea can be used for pretty much any type.

$\endgroup$

You must log in to answer this question.

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