Yes, it is possible if you use an invoke()
method in your operator instead of execute()
, because there's a 3rd parameter given to invoke - an event object.
That object has attributes about modifier key states among a few other pieces of input info.
Here's an example script, that adds a button to the 3D View. You can hold e.g. CtrlShift down and click on it to let the operator report Ctrl+Alt+Click
in the info area:
import bpy
class SimpleOperator(bpy.types.Operator):
"""Tooltip"""
bl_idname = "object.simple_operator"
bl_label = "Simple Object Operator"
@classmethod
def poll(cls, context):
return context.active_object is not None
def invoke(self, context, event):
ev = []
if event.ctrl:
ev.append("Ctrl")
if event.shift:
ev.append("Shift")
if event.alt:
ev.append("Alt")
if event.oskey:
ev.append("OS")
ev.append("Click")
self.report({'INFO'}, "+".join(ev))
return {'FINISHED'}
def draw_func(self, context):
self.layout.operator(SimpleOperator.bl_idname)
def register():
bpy.utils.register_class(SimpleOperator)
bpy.types.VIEW3D_HT_header.prepend(draw_func)
def unregister():
bpy.utils.unregister_class(SimpleOperator)
bpy.types.VIEW3D_HT_header.remove(draw_func)
if __name__ == "__main__":
register()
Note that there can also be an execute()
method in the operator, but it won't be called unless the execution context is not INVOKE_*
, but EXEC_*
. The default behavior of the Python Console is, for instance, to execute an operator, not to invoke it.
If there's no execute()
and you run bpy.ops.object.simple_operator()
in the console, an error will be reported in the System Console and the operator abort with {'PASS_THROUGH'}
. You can explicitly invoke it however: bpy.ops.object.simple_operator('INVOKE_DEFAULT')