1
$\begingroup$

I am trying to create three toggle widgets to work together. The workflow I am trying obtain is when one toggle is clicked the other two toggle widgets get their states set to False programmatically.

import bpy

def toggle_ui(a_bool=True, b_bool=True, c_bool=True):
    bpy.data.scenes['Scene'].type_a=a_bool
    bpy.data.scenes['Scene'].type_b=b_bool
    bpy.data.scenes['Scene'].type_c=c_bool

def tgl_a(self, context):
    print("my test function", self)
    print(self.type_a)
    # toggle_ui(True, False, False)
    bpy.data.scenes['Scene'].type_b = False
    bpy.data.scenes['Scene'].type_c = False

def tgl_b(self, context):
    print("my test function", self)
    print(self.type_b)
    # toggle_ui(False, True, False) 
    bpy.data.scenes['Scene'].type_a = False
    bpy.data.scenes['Scene'].type_c = False

def tgl_c(self, context):
    print("my test function", self)
    print(self.type_c)
    # toggle_ui(False, False, True)
    bpy.data.scenes['Scene'].type_a = False
    bpy.data.scenes['Scene'].type_b = False

bpy.types.Scene.type_a = bpy.props.BoolProperty(update=tgl_a)
bpy.types.Scene.type_b = bpy.props.BoolProperty(update=tgl_b)
bpy.types.Scene.type_c = bpy.props.BoolProperty(update=tgl_c)

class HelloWorldPanel(bpy.types.Panel):
    """Creates a Panel in the Object properties window"""
    bl_label = "Hello World Panel"
    bl_idname = "OBJECT_PT_hello"
    bl_space_type = 'VIEW_3D'
    bl_region_type = 'UI'
    bl_context = "object"

    def draw(self, context):
        layout = self.layout
        layout.prop(bpy.data.scenes['Scene'], "type_a", text="a")
        layout.prop(bpy.data.scenes['Scene'], "type_b", text="b")
        layout.prop(bpy.data.scenes['Scene'], "type_c", text="c")

def register():
    bpy.utils.register_class(HelloWorldPanel)


def unregister():
    bpy.utils.unregister_class(HelloWorldPanel)


if __name__ == "__main__":
    register()

Whenever I run this bit of code and click on any toggle widget, Blender explodes. It would be great if some one can nudge me in the direction on how to set this up properly in Blender.

Thanks in advance.

A.Kal

$\endgroup$
  • $\begingroup$ Infinite recursion. If you change one of the toggles, it changes others. Which calls update functions again and again, etc. $\endgroup$ – kilbee Oct 5 '15 at 22:07
1
$\begingroup$

If you call an update function on every value change, you will go into infinite loop without condition check (every update function calls other update functions). So first make sure that you change value only, if value for given bool property is True

import bpy

def toggle_ui(a_bool=True, b_bool=True, c_bool=True):
    bpy.data.scenes['Scene'].type_a=a_bool
    bpy.data.scenes['Scene'].type_b=b_bool
    bpy.data.scenes['Scene'].type_c=c_bool

def tgl_a(self, context):
    print("my test function", self)
    print(self.type_a)
    # toggle_ui(True, False, False)
    #print(type_a)
    if bpy.data.scenes['Scene'].type_a == True:
        bpy.data.scenes['Scene'].type_b = False
        bpy.data.scenes['Scene'].type_c = False

def tgl_b(self, context):
    print("my test function", self)
    print(self.type_b)
    # toggle_ui(False, True, False)
    if bpy.data.scenes['Scene'].type_b == True:
        bpy.data.scenes['Scene'].type_a = False
        bpy.data.scenes['Scene'].type_c = False

def tgl_c(self, context):
    print("my test function", self)
    print(self.type_c)
    # toggle_ui(False, False, True)
    if bpy.data.scenes['Scene'].type_c == True:
        bpy.data.scenes['Scene'].type_a = False
        bpy.data.scenes['Scene'].type_b = False

bpy.types.Scene.type_a = bpy.props.BoolProperty(update=tgl_a)
bpy.types.Scene.type_b = bpy.props.BoolProperty(update=tgl_b)
bpy.types.Scene.type_c = bpy.props.BoolProperty(update=tgl_c)

class HelloWorldPanel(bpy.types.Panel):
    """Creates a Panel in the Object properties window"""
    bl_label = "Hello World Panel"
    bl_idname = "OBJECT_PT_hello"
    bl_space_type = 'VIEW_3D'
    bl_region_type = 'UI'
    bl_context = "object"

    def draw(self, context):
        layout = self.layout
        layout.prop(bpy.data.scenes['Scene'], "type_a", text="a")
        layout.prop(bpy.data.scenes['Scene'], "type_b", text="b")
        layout.prop(bpy.data.scenes['Scene'], "type_c", text="c")

def register():
    bpy.utils.register_class(HelloWorldPanel)


def unregister():
    bpy.utils.unregister_class(HelloWorldPanel)


if __name__ == "__main__":
    register()
$\endgroup$

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.