Keymap for addons

Hi,

I’m trying to add keymaps in the preferences of my addons.
Sombody have a code for that I can use ?

Don’t know if you seen this or if it helps any. http://blender.stackexchange.com/questions/1497/how-can-i-call-a-specific-keymap-to-draw-within-my-addonpreferences

kilbee helped me so I made a template to help all devs to add keymaps to their addons.


You can find the file there.

Tell me if you have any issue with it :wink:

6 Likes

This and also this https://blenderartists.org/forum/showthread.php?399298-Rename-Tabs-Function would be a nice addition to blenders python templates.

1 Like

Good idea, we need this kind of code to improve the usability of the addons.

Maybe the devs can make something simpler and better.

There is one issue:
If you remove created hotkey manually (from Input tab or directly from addon preferences) then creating new hotkey won’t save it across sessions - after unregister/register addon (or after blender restart)…
The simple way to get around this is to go to Input tab and reset whole section (where the hotkey is listed) to defaults, then it will automatically reappear.
I guess there is some problem with keeping addon keymap with user keymap in sync when removing hotkey manually, but not sure how to do that.

well… I’ve came up with solution - but I don’t think this is how it should be done :wink:
I just define list of hotkeys (with all parameters) and add them directly to keyconfig.user. It nicely registers/unregisters without all that keyconfig.addon stuff, which I can’t seem to understand properly.
Anyway, take a peek http://github.com/kilbee/kbPIEs/blob/master/kbPIEs.py
It handles multiple hotkeys per addon and doesn’t interfere with other addons, but I don’t think this is clean enough for a template ;D

Would be great if someone with better understanding of hotkey registering to keymaps explained how to go around the issue in a cleaner way.

edit:
Oh… just reading through that post AFWS linked from stackexchange - it seems to be a bug with removing a hotkey:

  • There is one bug at the moment, pressing the ‘X’ buttons isn’t properly removing them. (needs further investigation we should be able to fix)

So I guess there is no better solution for now.

1 Like

Thanks for that pitiwazou. It was very helpful in fixing my gropPro hotkeys setup.

pitiwazou Thank you very much

thank you very much for this thread !

related

Guys,

Do you have an idea why the keymap only work on Blender and not industry standart?

I tried to use active instead of user or addon, I have the same result.
The keympap only work on blender default.

EDIT: The issue isn’t the industry mode, but the other keymap that I need to disable.

Somebody know how to edit an existing keymap?

Change the keys of Play Animation from space to something else for example.

The way I override gpencile draw :

if ‘Grease Pencil’ in bpy.context.window_manager.keyconfigs.user.keymaps.keys():
bpy.context.window_manager.keyconfigs.user.keymaps[‘Grease Pencil’].keymap_items[‘gpencil.annotate’].active = False

Then write new key:

km = wm.keyconfigs.addon.keymaps.new(name=‘Object Mode’, space_type=‘EMPTY’)
kmi = km.keymap_items.new(‘object.draw_hair_surf’, main_key, main_key_state, any=is_any_pressed, shift=is_shift_pressed,
ctrl=is_ctrl_pressed, alt=is_alt_pressed, oskey=is_os_pressed, key_modifier=key_mod)
# - mem custom key edit above - # kmi = km.keymap_items.new(‘object.draw_hair_surf’, ‘LEFTMOUSE’, ‘PRESS’, key_modifier=‘D’)
addon_keymaps.append((km, kmi))

AFAIK, the second would not work without disabling gpencil. I think gpencil would be registered as second hotkey, so it would override new key, that is why wy disable it.

Ok, I will test, thx :wink:

Here’s my cave-man way of deactivating keymaps.

wm = bpy.context.window_manager
kc = wm.keyconfigs.user

    for K in kc.keymaps["Frames"].keymap_items:
        if K.idname == "screen.animation_play" and K.active:
            print(f"!!--DEBUG MESSAGE--!! Deactivating {K.idname}")
            K.active = False

    for K in kc.keymaps["Object Mode"].keymap_items:
        if (
            K.idname == "wm.tool_set_by_id"
            and K.properties.name == "builtin.select_box"
            and K.type == "Q"
            and K.active
        ):
            print(f"!!--DEBUG MESSAGE--!! Deactivating {K.properties.name}")
            K.active = False
        if (
            K.idname == "wm.tool_set_by_id"
            and K.properties.name == "builtin.annotate"
            and K.type == "D"
            and K.active
        ):
            print(f"!!--DEBUG MESSAGE--!! Deactivating {K.properties.name}")
            K.active = False

I loop thru each keymaps key and add conditional if statements to deactivate the correct items.

1 Like

This is perfect, thank you!

To edit an existing shortcut, this is as simple as that.

wm = bpy.context.window_manager
kc = wm.keyconfigs.user

for k in kc.keymaps["Frames"].keymap_items:
    if k.idname == "screen.animation_play" and k.active:
        k.active = True
        k.type = 'Q'
        k.value = 'PRESS'
        k.shift = True
        k.ctrl = True
        k.alt = True
3 Likes

I’ve made a user-modifiable keymap menu with a more concise source code, so share it.
There is no need to specify the key map name or registration location in the menu.


Keys that match add-on keymaps registered in the “addon_keymaps” list,
Search from the key map settings of Blender and display.
The key map registration location is also displayed.

# Search for keymap items in the addon's keymap list (addon_keymaps) from within Blender settings and display the menu

import rna_keymap_ui 


box = layout.box()
col = box.column()
col.label(text="Keymap List:",icon="KEYINGSET")


wm = bpy.context.window_manager
kc = wm.keyconfigs.user
old_km_name = ""
get_kmi_l = []
for km_add, kmi_add in addon_keymaps:
    for km_con in kc.keymaps:
        if km_add.name == km_con.name:
            km = km_con
            break

    for kmi_con in km.keymap_items:
        if kmi_add.idname == kmi_con.idname:
            if kmi_add.name == kmi_con.name:
                get_kmi_l.append((km,kmi_con))

get_kmi_l = sorted(set(get_kmi_l), key=get_kmi_l.index)

for km, kmi in get_kmi_l:
    if not km.name == old_km_name:
        col.label(text=str(km.name),icon="DOT")
    col.context_pointer_set("keymap", km)
    rna_keymap_ui.draw_kmi([], kc, km, kmi, col, 0)
    col.separator()
    old_km_name = km.name

5 Likes

can you please tell me where to add these code ? In an preference class or in the register function? :astonished:

This is a menu, no other functions are needed.
Locations are typically placed in a menu in add-on settings(AddonPreferences Class).
All else needed is a list of keymap items called “addon_keymaps”.

The code had some points to be improved, so I changed it to the latest code.

2 Likes