How to create toggle button use python in blender I want to make a toggle button for my custom operator. It works similar to checkbox: once the button is clicked, the operator keeps running until the button gets another click, so will the button itself greyed out. I tried to achieve the grey-out effect by implementing poll() function like this:

@classmethod
def poll(cls, context):      
    return context.area.type == 'VIEW_3D' and context.region.type == 'WINDOW' and plane_toggle_flag


Every time the button is clicked I want the toggle state to change, so in the operator's init(), I write:

def __init__(self):   
    plane_toggle_flag=not plane_toggle_flag


However, it seems as long as poll() returns false, the init() function never get the chance to be called. Any idea how to solve this? Thank you in advance.
Create a bool property for Window Manager (it can be for anything, but WM will store our modal operator handler so why not put this in the same place):

bpy.types.WindowManager.my_operator_toggle = bpy.props.BoolProperty()

Display it somewhere in the UI with the toggle tag on:

layout = self.layout
wm = context.window_manager
label = "Operator ON" if wm.my_operator_toggle else "Operator OFF"
layout.prop(wm, 'my_operator_toggle', text=label, toggle=True)


It looks like this:


Create your modal operator (example of basic timer):

class SomeModalOperator(bpy.types.Operator):
    bl_idname = "my.operator"
    bl_label = "My Operator"

    def modal(self, context, event):
        print("running")
        if not context.window_manager.my_operator_toggle:
            context.window_manager.event_timer_remove(self._timer)
            return {'FINISHED'}
        return {'PASS_THROUGH'}

    def invoke(self, context, event):
        self._timer = context.window_manager.event_timer_add(0.01, context.window)
        context.window_manager.modal_handler_add(self)
        return {'RUNNING_MODAL'}


The operator ends itself when the bool property is False.
Add update function to the bool property that will run the operator:

def update_function(self, context):
    if self.my_operator_toggle:
        bpy.ops.my.operator('INVOKE_DEFAULT')
    return

bpy.types.WindowManager.my_operator_toggle = bpy.props.BoolProperty(
                                                 default = False,
                                                 update = update_function)



The modal operator is useful when you need to handle user input. For anything else it is better to use app.handlers, you can toggle them through bool property in similar fashion.