10
$\begingroup$

The add-on I've written defines several custom hotkeys, allowing the user to call custom menus created by the add-on. To be more user-friendly, I'd like to make it easy for the user to change the hotkeys for these menus without needing to dig through the massive keymap list under User Preferences > Input.

And so I have created AddonPreferences, in which the user can adjust settings for the add-on.

Is there a way to pull in, and draw the specific keymap item (from Input) within the AddonPreferences?

$\endgroup$
10
$\begingroup$

You're likely the first person who has attempted this, and it looks like its quite possible;

Notes

  • Save this script to your addons dir with a unique name (ending with .py)
  • The keymaps are added as is normal for an addon.
  • 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)
  • Finally - this uses a part of the API we consider internal, so its not guaranteed to work in future versions (realistically it probably wont change any time soon though).

Script:

bl_info = {"name": "KeyMap Test", "category": "Object"}

import bpy
from bpy.types import Operator, AddonPreferences
from bpy.props import StringProperty, IntProperty, BoolProperty

# this is an internal API at the moment
import rna_keymap_ui


class ExampleAddonPreferences(AddonPreferences):
    # this must match the addon name, use '__package__'
    # when defining this in a submodule of a python package.
    bl_idname = __name__

    filepath = StringProperty(
            name="Example File Path",
            subtype='FILE_PATH',
            )
    number = IntProperty(
            name="Example Number",
            default=4,
            )
    boolean = BoolProperty(
            name="Example Boolean",
            default=False,
            )

    def draw(self, context):
        layout = self.layout
        layout.label(text="This is a preferences view for our addon")
        layout.prop(self, "filepath")
        row = layout.row()
        row.prop(self, "number")
        row.prop(self, "boolean")

        col = layout.column()
        kc = bpy.context.window_manager.keyconfigs.addon
        for km, kmi in addon_keymaps:
            km = km.active()
            col.context_pointer_set("keymap", km)
            rna_keymap_ui.draw_kmi([], kc, km, kmi, col, 0)


class OBJECT_OT_addon_prefs_example(Operator):
    """Display example preferences"""
    bl_idname = "object.addon_prefs_example"
    bl_label = "Addon Preferences Example"
    bl_options = {'REGISTER', 'UNDO'}

    def execute(self, context):
        user_preferences = context.user_preferences
        addon_prefs = user_preferences.addons[__name__].preferences

        info = ("Path: %s, Number: %d, Boolean %r" %
                (addon_prefs.filepath, addon_prefs.number, addon_prefs.boolean))

        self.report({'INFO'}, info)
        print(info)

        return {'FINISHED'}


addon_keymaps = []

# Registration
def register():
    bpy.utils.register_class(OBJECT_OT_addon_prefs_example)
    bpy.utils.register_class(ExampleAddonPreferences)

    # Keymapping
    kc = bpy.context.window_manager.keyconfigs.addon
    km = kc.keymaps.new(name="3D View", space_type='VIEW_3D')
    kmi = km.keymap_items.new("object.editmode_toggle", 'NUMPAD_SLASH', 'PRESS', shift=True)
    kmi.active = True
    addon_keymaps.append((km, kmi))
    kmi = km.keymap_items.new("object.transform_apply", 'NUMPAD_SLASH', 'PRESS', shift=True)
    kmi.active = True
    addon_keymaps.append((km, kmi))


def unregister():
    bpy.utils.unregister_class(OBJECT_OT_addon_prefs_example)
    bpy.utils.unregister_class(ExampleAddonPreferences)

    # handle the keymap
    for km, kmi in addon_keymaps:
        km.keymap_items.remove(kmi)
    addon_keymaps.clear()
$\endgroup$
  • 1
    $\begingroup$ This is exactly what I need! Thanks so much. $\endgroup$ – Jonathan Williamson Jun 29 '13 at 3:44
  • $\begingroup$ With the recent API changes, that are so far undocumentated, how can I go about this? $\endgroup$ – Jonathan Williamson Aug 19 '13 at 23:57
  • $\begingroup$ Updated, only very minor changes, see rna_keymap_ui use. $\endgroup$ – ideasman42 Aug 20 '13 at 2:51
  • $\begingroup$ In Blender 2.8 the keymaps are not persisted when doing it this way. Any ideas? $\endgroup$ – Jayanam Jan 18 '19 at 21:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.