Skip to content

Quicker Text Editing in Blender (Part 3): Keymaps

  • by

<Here be keys>


I’ve been using Blender to make videos using its VSE, and I use text sequences for captions. But doing so involves a lot of repetitive setting of various things- colour, position, size, duration; so I’d like to speed up that process, rather than faff about setting them in the sidebar. My videos can have a lot of text sequences!

Last time we wrote some code to generate Operators (the Blender type) dynamically based on Enums- so we can have, say, an enum of colours:

class Colours(Enum):
    GREEN = (0, 1, 0, 1)
    PURPLE = (0.7, 0, 0.7, 1)
    BLUE = (0, 0, 1, 1)

and get a nice set of operators:

Quicker Access Using Hotkeys

Thanks to guidance from iceythe on BlenderArtists, we can create key bindings to run operators. We can even use the more generic SetTextColour operator by setting a property on the keybinding, which will work like an argument has been passed. In their words:

To answer your original question regarding hotkeys; when you create a hotkey, the object returned is what’s called an OperatorProperties instance. You can set predefined arguments on these just like you would when defining button operators in layouts.

part of a reply on blenderartists

Even better, they ‘gib teh codes‘ and provided examples of how to implement that. It is, as they note, a lot of boilerplate for setting them up, but we’ll use that to make hotkeys for our operators. For example, for the colour operators:

class SetTextColour(TextSequenceAction):
    """Set colour of text sequence[s]"""
    bl_idname = "sequencer.settextcolor"
    bl_label = "Set Text Colour"

    colour: bpy.props.FloatVectorProperty(
        description="Colour for text",
        default=(0.0, 0.0, 0.0, 1),  # black in RGBA

    _colour = None

    _keymaps = []

    def __init__(self):
        if self._colour:
            self.colour = self._colour

    def execute(self, context):
        for strip in bpy.context.selected_editable_sequences:
            if strip.type == "TEXT":
                strip.color = self.colour

        return {'FINISHED'}

    def register(cls):
        # Boilerplate
        wm = bpy.context.window_manager
        km = wm.keyconfigs.addon.keymaps.get("Sequencer")
        if km is None:
            km =
                "Sequencer", space_type='SEQUENCE_EDITOR')

        # 'ctrl + shift + g' -> SetTextColour(color=Colours.GREEN.value)
        kmi =,
                                  'G', 'PRESS', ctrl=True, shift=True) = Colours.GREEN.value
        cls._keymaps.append((km, kmi))
        kmi = None

        # 'ctrl + shift + b' -> SetTextColour(color=Colours.BLUE.value)
        kmi =,
                                  'B', 'PRESS', ctrl=True, shift=True) = Colours.BLUE.value
        cls._keymaps.append((km, kmi))
        print({'INFO'}, f"_keymaps: {cls._keymaps}")

        # 'ctrl + shift + p' -> SetTextColour(color=Colours.PURPLE.value)
        kmi =,
                                  'P', 'PRESS', ctrl=True, shift=True) = Colours.PURPLE.value
        cls._keymaps.append((km, kmi))
        print({'INFO'}, f"_keymaps: {cls._keymaps}")

    def unregister(cls):
        # Remove keymaps when operator is unregistered
        for km, kmi in cls._keymaps:

Gives us:

Wonderful! The keys are displayed using Screencast-Keys

So we have a decent way of quickly setting colour without our hands leaving the keyboard.

Next Steps

There’s a couple of next steps:

  1. for my own use, I can produce a version with the presets (colour/position/size/duration) hard-coded, as this would let me crack on making videos, which I put on hold to write this script/addon†
  2. for general use, I would want to give the user the ability to define and customise themselves- let them set presets and the hotkeys for them as they see fit

†: in the ‘proactive laziness’ sense- ie don’t do something slowly/inefficiently/cumbersomely if you’re about to do something to make it much easier!

Tell us what's on your mind

Discover more from Rob's Blog

Subscribe now to keep reading and get access to the full archive.

Continue reading