0
$\begingroup$

I am studying Python programming for Blender and recently started dealing with modal operators. The question I have is: There is a double call from the event of the modal operator for key-up and key-down of the specific keys. How can that be reduced to one call? Also, this is useful if it runs silently in the background without taking up resources. Is this the case for the modal operator, or are there caveats?

Here is the derivative code I'm working with that displays to the console:

import bpy

class ModalOperator(bpy.types.Operator):
    bl_idname = "object.modal_operator"
    bl_label = "Simple Modal Operator"

    def execute(self, context):
        print("This is the modal operator")
        return {'FINISHED'}

    def modal(self, context, event):
        if event.type == 'ESC':  # Confirm
            print("This is finished")
            return {'FINISHED'}
        elif event.alt:
            if event.type == 'P':  # Confirm
                print("This is a continuous pass through")
            return {'PASS_THROUGH'}

        return {'PASS_THROUGH'}

    def invoke(self, context, event):
        print("This is the invoker")

        context.window_manager.modal_handler_add(self)
        return {'RUNNING_MODAL'}

bpy.utils.register_class(ModalOperator)

bpy.ops.object.modal_operator('INVOKE_DEFAULT')
$\endgroup$
  • 1
    $\begingroup$ Is Event.value eg if event.type == 'P' and event.value == 'PRESS' what you are looking for? $\endgroup$ – batFINGER Feb 9 '17 at 16:17
  • $\begingroup$ Yes. Its going to track all input anyway, but triggering an event once is what I was looking for. Is there an advantage to using: if event.type == 'P' and event.value == 'PRESS' ' vs. if event.type == 'P': if event.value == 'PRESS': other than brevity? $\endgroup$ – ACopeLan Feb 9 '17 at 21:19
2
$\begingroup$

Thanks again batFINGER

The following works great:

import bpy

class ModalOperator(bpy.types.Operator):
    bl_idname = "object.modal_operator"
    bl_label = "Simple Modal Operator"

    def execute(self, context):
        print("This is the modal operator")
        return {'FINISHED'}

    def modal(self, context, event):
        if event.type == 'ESC':  # Confirm
            print("This is finished")
            return {'FINISHED'}
 # .value == 'PRESS' will trigger the event once. 
 # or do: if event.type == 'P' and if.event.value == 'PRESS':
        elif event.alt:
            if event.type == 'P':
                if.event.value == 'PRESS': # Confirm
                    print("This is a continuous pass through")
            return {'PASS_THROUGH'}

        return {'PASS_THROUGH'}

    def invoke(self, context, event):
        print("This is the invoker")

        context.window_manager.modal_handler_add(self)
        return {'RUNNING_MODAL'}

bpy.utils.register_class(ModalOperator)

bpy.ops.object.modal_operator('INVOKE_DEFAULT')
$\endgroup$
0
$\begingroup$

There's also the "RELEASE" event, eg:

event.type == 'LEFTMOUSE' and event.value == 'RELEASE'
$\endgroup$
  • $\begingroup$ The release event is another method that can be used. $\endgroup$ – ACopeLan Feb 12 '17 at 2:17

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.