Page 1 of 1

Basic Modal Operator Script - Modal() Function Never Runs

Posted: Tue May 21, 2013 7:44 am
by BlazeCell
I have a basic modal operator script with just some print commands to track program flow. Based on the output to the console, the invoke() function is the only one ever being run, never the modal() function, even though I have execute(), invoke() and modal() return {'RUNNING_MODAL'}.

Code: Select all

bl_info = {
    "name": "Test Script - Modal",
    "author": "BlazeCell",
    "version": (0, 1),
    "blender": (2, 66, 1),
    "location": "View3D > Mesh > Vertices (Ctrl+V)",
    "warning": "",
    "description": "Test Script Modal",
    "wiki_url": "",
    "tracker_url": "",
    "category": "Mesh"}
 
import bpy
 
class TestModal(bpy.types.Operator):
    """Test Script - Modal"""
    bl_idname = "mesh.test_modal"
    bl_label = "Test Modal"
 
    def __init__(self):
        print('START')
 
    def __del__(self):
        print('END')
 
    def execute(self, context):
        print('EXECUTE')
 
        return {'RUNNING_MODAL'}
 
    def modal(self, context, event):
        print('MODAL')
 
        return {'RUNNING_MODAL'}
 
    def invoke(self, context, event):
        print('INVOKE')
 
        return {'RUNNING_MODAL'}
 
def register():
    bpy.utils.register_class(TestModal)
 
def unregister():
    bpy.utils.unregister_class(TestModal)
 
if __name__ == "__main__":
    register()
Am I missing something, or is there bug in Blender 2.66.1 with modal operator scripts?

Posted: Tue May 21, 2013 10:36 am
by CoDEmanX
there should be no execute() in a modal operator, it isn't run.

You need to add a modal handler:

Code: Select all

import bpy

class ModalOperator(bpy.types.Operator):
    """Move an object with the mouse, example"""
    bl_idname = "object.modal_operator"
    bl_label = "Simple Modal Operator"

    def modal(self, context, event):
        
        print("MODAL")
        
        if event.type in {'RIGHTMOUSE', 'ESC'}:
            print("END")
            return {'CANCELLED'}

        return {'RUNNING_MODAL'}

    def invoke(self, context, event):
        print("INVOKE")
        
        context.window_manager.modal_handler_add(self) # add modal handler!!!
        return {'RUNNING_MODAL'}

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


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


if __name__ == "__main__":
    register()

Posted: Tue May 21, 2013 12:40 pm
by BlazeCell
Thank you so much! I have spent too many hours banging my head against the wall on how to get modal operators working. :D