I have a custom python file where I setup my keymaps like this:

kmi = km.keymap_items.new('mesh.select_linked_pick', 'LEFTMOUSE', 'DOUBLE_CLICK').properties.deselect = False

How come I can do that for Blender's default operators but NOT for my custom operators. Whenever I try it always throws an error saying whatever property I'm setting doesn't exist. For example:

kmi = km.keymap_items.new('armored.zero_vertex', 'X', 'PRESS', alt=True).properties.axis = 'X'

enter image description here

The operator itself does work and the custom property does affect the code correctly depending on its value (when run from blender's console bpy.ops.armored.zero_vertex(axis='X')), it just doesn't work from the Keymap file.

Note that this keymap works if I place it in the operator's own registration function, which leads me to assume that Blender's operators get registered way before and that's why their properties are already available while the properties for my operators are not.

Both my Operator and my Keymap file are inside the startup/scripts folder, their name and order in that folder seems to be irrelevant.

  • 2
    $\begingroup$ Would recommend not using the shortcut notation of kmi = km.keymap_items.new('armored.zero_vertex', 'X', 'PRESS', alt=True).properties.axis = 'X' and rather kmi = km.keymap_items.new('armored.zero_vertex', 'X', 'PRESS', alt=True) followed by kmi.properties.foo = "bar" then kmi.properties.bar = "foo" for another. Otherwise kmi is not going to be a keymap item if used later. $\endgroup$
    – batFINGER
    Commented Nov 2, 2020 at 11:34

1 Answer 1


I believe the .axis appended to the end of the .new() constructor may be throwing your solution - it's being seen as an attribute of your keymap's properties, rather than referencing an idname for the operator which I believe is in your case armored.zero_vertex

Here is an example of an implementation of a custom keymap applied to a hidden operator. It might be useful for reference:

The class definition surfaces the custom/hidden operator with its bl_idname

# Surfacing the Operators
# They can now be looked up via their bl_label attribute with the search function on default hotkey F3

class PREFERENCES_OT_toggle_emulate_3_button_mouse(bpy.types.Operator):
    bl_idname = "preferences.toggle_emulate_3_button_mouse"
    bl_label = "Toggle 'Emulate 3 Button Mouse'"

    def execute(self, context):
        context.preferences.inputs.use_mouse_emulate_3_button = not context.preferences.inputs.use_mouse_emulate_3_button
        return {"FINISHED"}

And then the keymap is applied:

km = wm.keyconfigs.addon.keymaps.new(name=idname, space_type=space_type)

kmi = km.keymap_items.new(idname, type, value, ctrl=true)

properties = kmi.get("properties")

for name, value in properties:
   setattr(kmi.properties, name, value)

keymaps = keymaps.append((km,kmi))
  • 1
    $\begingroup$ Oops commented same before reading answer. Maybe print the value kmi is given if using the shortcut notation and without would be another way to demonstrate. $\endgroup$
    – batFINGER
    Commented Nov 2, 2020 at 11:38

You must log in to answer this question.

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