# Python: Ctrl+Click for buttons (capture invocation event)

Is it possible to get if Ctrl key is pressed when I click on my python button?

I would like make different behaviors for my button operator.

Example:
LMB - Select some objects
CtrlLMB - Deselect some objects

I don't use a modal operator / the modal() method. I've been making a simple script.

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)

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

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')

• As always you save me. You are my hero! – mifth Jan 30 '15 at 10:26
• You're welcome. On a side note: It's not possible to let the button change (label or icon) based on the held down modifier keys. Actually it is, but only if you monitor their state continuously - which would require a modal operator running in the background all the time. Plus, you would need to tag_redraw() the region. See my prototype over here: blenderartists.org/forum/… – CoDEmanX Jan 30 '15 at 10:34
• great answer, you made a touched on few points here that I tripped over for a while before I figured it out. – David Jan 30 '15 at 18:46
• @CoDEmanX I've been looking for a solution to a recent problem I encountered. For my problem, I need to click on a node in the node editor to trigger LBM clicking so that the values of the 'Image Node` block get updated. I think a version of your solution will provide me what I want but I do not know how I can adapt your answer. Could you take a look at my question here and let me know if you think I am doing something wrong? – Amir Mar 10 '18 at 19:50