2
$\begingroup$

Consider the following script block:

import bpy
wm = bpy.context.window_manager    # get window manager
_defaultkm = wm.keyconfigs.default.keymaps    # get default keymap

# try retrieving the keymap_item for the view3d.move operator
# unfortunately, keymap_items at register() time is always empty
_move = _defaultkm['3D View'].keymap_items.get('view3d.move')
_move.active = False    # disable that item

It's purpose is to disable a specific shortcut which is shipped with Blender. If you run this in the Text Editor within a Blender session, it works as I wished and disables one of the standard keymap items.

However, my issue is that I'd like to run that code within the register() function of an Add-on. Within that function, _defaultkm will hold a valid Python object, but keymap_items contains no items at all and get() always returns None, causing the last line of the code to fail. It's worth noting that this fails on all different tricks of retrieving keymaps (such as the one mentioned here), it seems as if I can only access my own Add-on keymaps from within the module registration code.

Is there a way to circumvent this?

Edit

I tried a solution using a persistent frame change handler, hooked up to the load_post event. Still, I was unable to access and change the keymap from there, the issue is the same.

$\endgroup$
22
  • 1
    $\begingroup$ Not 100% sure what your issue is, started from scratch and it's working well. I can enable and disable Shift+MMB as expected: gist.github.com/p2or/fea39e610552b80b40533fc99934b772 $\endgroup$
    – p2or
    Commented Jun 21, 2018 at 13:31
  • $\begingroup$ @p2or Thanks for your gist, it works indeed as expected. However, if I copy/paste it into my own add-on, the keymap again is reported as empty. The only fundamental difference I can make out is that my add-on is a multifile one, which registers itself using register_module(__name__). Your solution might still be working for me, as I can put an extra add-on into the startup section, so it auto-loads. $\endgroup$
    – aliasguru
    Commented Jun 21, 2018 at 14:00
  • $\begingroup$ @p2or ok, it's not the multifile thing. With your add-on, I get the same error. It works when the user activates it in the Add-ons manager, but if you hit Save User Settings, close Blender and re-open, the same issue arises. $\endgroup$
    – aliasguru
    Commented Jun 21, 2018 at 14:11
  • $\begingroup$ @p2or the error message is Exception in module register(): 'D:\_PREFS_REFACTOR_\_REFACTOR_\\scripts\\addons\\blender-deactivate-shift-MMB.py' Traceback (most recent call last): File "C:\blender-git\build_windows_Full_x64_vc15_Release\bin\Release\2.80\scripts\modules\addon_utils.py", line 363, in enable mod.register() File "D:_PREFS_REFACTOR__REFACTOR_\scripts\addons\blender-deactivate-shift-MMB.py", line 21, in register wm.keyconfigs.default.keymaps['3D View'].keymap_items['view3d.move'].active = False KeyError: 'bpy_prop_collection[key]: key "view3d.move" not found' $\endgroup$
    – aliasguru
    Commented Jun 21, 2018 at 14:11
  • 1
    $\begingroup$ Yeah you are right, KeyMap("3D View") collection is empty for whatever reason . However, you can overwrite the existing one by assigning view3d.rotate operator: gist.github.com/p2or/0969e9981aeec63551e8f0b02e0c7d55 (to make it work at least) @aliasguru. $\endgroup$
    – p2or
    Commented Jun 21, 2018 at 16:16

1 Answer 1

1
$\begingroup$

I had similar problems when tried to modify default key maps with python. The keymap_items collection was empty at startup script but after the start, items were accessible.

The problem was solved using thread and time.sleep It is not the best approach but working..

The load_post handler didn't work for application start but worked for file open.

I didn't find any "start_post" handler method.

here is the first code (startup scripts folder):

import bpy

wm = bpy.context.window_manager
kc = wm.keyconfigs.default
km = kc.keymaps['Screen Editing']
print('item count:',len(km.keymap_items))

#> "item count: 0"

here is the solved version

import bpy,_thread,time


wm = bpy.context.window_manager
kc = wm.keyconfigs.default
km = kc.keymaps['Screen Editing']


def thrd_func():
    time.sleep(.1)
    print('item count:',len(km.keymap_items))

_thread.start_new_thread(thrd_func,())


#> "item count: 12"

and with handler

import bpy
from bpy.app.handlers import persistent

@persistent
def hand_func(arg):
    wm = bpy.context.window_manager
    kc = wm.keyconfigs.default
    km = kc.keymaps['Screen Editing']
    print('item count:',len(km.keymap_items))

bpy.app.handlers.load_post.append(hand_func)
$\endgroup$

You must log in to answer this question.

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