4
$\begingroup$

In blender interface, when multiple objects are selected if we press "ALT" on the keyboard while changing a property, the behavior of the property execution change (in this case we can batch change every selected objects at the same time)

How can I have a similar behavior with my python bpy.props properties ? is there a way to tell if the user is pressing "ALT" from my prop update function? How can I make my property run a different execution if my user is pressing the ALT key when interacting with my prop from the GUI for example?

Thanks

$\endgroup$
0

1 Answer 1

9
$\begingroup$

What i really need is bpy.Types.event, unfortunately, it is only accessible from an Operator invoke() or modal()

so here's the trick

_event = None  

class SCATTER5_OT_get_event(bpy.types.Operator):
    bl_idname  = "scatter5.get_event"
    bl_label   = ""

    def invoke(self, context, event):
        global _event
        _event = event
        return {'FINISHED'}

def get_event():
    global _event
    bpy.ops.scatter5.get_event('INVOKE_DEFAULT')
    return _event
event = get_event()

to get event from anywhere in your script

what would have been be nice is something like bpy.context.window_manager.event, unfortunately this API does not exist (not sure why this type is only accessible from operators?)

Also, it would be ideal if there was a built-in python module that can detect keyboard input, unfortunately, I didn't find one.

feel free to propose an alternative method


example of implementation by @batFINGER press alt/shift/ctrl/oskey while interacting with foo prop

import bpy
​
_event = None  
​
class SCATTER5_OT_get_event(bpy.types.Operator):
    bl_idname  = "scatter5.get_event"
    bl_label   = ""
​
    def invoke(self, context, event):
        global _event
        _event = event
        return {'FINISHED'}
​
def get_event(exec_context='INVOKE_DEFAULT'):
    global _event
    bpy.ops.scatter5.get_event(exec_context)
    return _event
​
def foo(self, context):
    event = get_event('INVOKE_REGION_WIN')
    print(
        "Shift" if event.shift else "",
        "Alt" if event.alt else "",
        "Ctrl" if event.ctrl else "",
        "OSKey" if event.oskey else "",
        event.value)
    
def draw(self, context):
    ob = context.object
    if ob:
        self.layout.prop(ob, "foo")
​
def register():
    bpy.types.Object.foo = bpy.props.IntProperty(
            update=foo,
            )
    bpy.utils.register_class(SCATTER5_OT_get_event)
    bpy.types.TEXT_HT_footer.prepend(draw)
    
if __name__ == "__main__":
    register()
$\endgroup$
1
  • $\begingroup$ Well, looks like 3.3 broke this code looks like _event = event reference is fading once operator is finished $\endgroup$
    – Fox
    Commented Aug 19, 2022 at 21:35

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .