spacr.qt.shortcuts

Keyboard-first shortcuts for the spaCR Qt GUI.

Registers global QShortcut bindings on the main window so the whole app is usable without a mouse:

Ctrl+0 Go home (Cmd+H is Hide on macOS) Ctrl+1..9 Switch to the Nth app in the sidebar Ctrl+K Open the command palette Ctrl+Shift+H Search spaCR from the field beside the Help menu F1 / ? Show the shortcuts cheat sheet Ctrl+P Open Preferences Ctrl+Alt+0 Put GUI scale, font scale and preview scales back to 100 % Ctrl+/ Open the AI Console Ctrl+End Jump to the newest console line F11 Toggle full screen Esc Close any open dialog / popup

install() is called once from MainWindow.__init__. Every binding is documented in SHORTCUTS so the cheat-sheet dialog stays in sync with what’s actually wired up.

Every window-wide key can be rebound. The cheat sheet carries a “Change shortcuts…” button that opens a table of the window-wide actions; a key typed there replaces the default, a key already taken by another action is named as a conflict and cannot be saved, and the overrides are kept in the Preferences store under _KEYMAP_KEY in Qt’s portable spelling, so a keymap saved on one platform reads the same on the others. Keys that belong to a single screen (Annotate, Make Masks, the field browser) have separate editable rows and saved overrides, applied to both existing and new screens.

Classes

ShortcutOverlay

The ? overlay — every shortcut, over the window, dismissed by any key.

ShortcutSpec

One shortcut declaration.

Functions

discover(→ List[ShortcutSpec])

Every shortcut LIVE on window, whether declared or not.

install(→ None)

Wire every shortcut in SHORTCUTS onto window.

installed(→ List[ShortcutSpec])

The window-wide keys that install() is responsible for binding.

mapped(→ List[ShortcutSpec])

Every shortcut the map describes: window-wide, then per-screen.

native(→ str)

keys in the spelling the user's own keyboard has.

show_cheat_sheet(→ None)

Show every registered shortcut, grouped by category.

Module Contents

class spacr.qt.shortcuts.ShortcutOverlay(window: PySide6.QtWidgets.QWidget)[source]

Bases: PySide6.QtWidgets.QWidget

The ? overlay — every shortcut, over the window, dismissed by any key.

A modal dialog was the wrong shape for this. The question a user asks by pressing ? is “what can I press here”, and the answer is worth about two seconds; a dialog with a title bar and a close button makes them commit to a mode, find the button, and leave it. An overlay dims what is behind, answers, and disappears on the next keystroke or click — including on ? itself, so the key that opened it also closes it.

Laid out in columns by category rather than one long list, because fifteen bindings in one column is a scroll and in three is a glance.

Parameters:

window – the window to cover and to read the bindings from. The overlay is drawn OVER it rather than as a dialog of its own, which is the whole argument above – so this is not a parent in the ordinary sense but the thing being annotated.

Build the shortcut cheat sheet as a card over the window.

Parameters:

window – the window it covers; the card is centred in it and scrolls when the map does not fit.

dismiss() → None[source]

Close the overlay and let go of the window.

eventFilter(obj, event)[source]

Track the window’s size so the overlay stays full-bleed.

Parameters:
  • obj – the watched object: the covered window or the card’s scroll viewport.

  • event – the event delivered to it. A resize of the window resizes the overlay to match; a mouse press on the scroll viewport dismisses the overlay and is consumed.

keyPressEvent(event) → None[source]

Any key closes it — that is the whole interaction.

Parameters:

event – the key event; which key was pressed is not read.

mousePressEvent(event) → None[source]

A click anywhere closes it too.

Parameters:

event – the mouse press event; its button and position are not read.

paintEvent(event) → None[source]

Leave the main window visible around the translucent shortcut card.

Parameters:

event – the paint event; ignored, so nothing is painted behind the card.

resizeEvent(event) → None[source]

Keep the card centred when the window resizes.

Parameters:

event – the resize event; not read, the card is re-centred for the overlay’s current size.

class spacr.qt.shortcuts.ShortcutSpec[source]

One shortcut declaration.

Parameters:
  • keys – the binding, in Qt’s portable spelling. It is PRINTED through QKeySequence.toString(NativeText), so Ctrl reads as the Command symbol on macOS – writing “Ctrl+H” into a label would hard-code one platform into the help.

  • label – what the key does.

  • category – the group it is shown under.

  • scope – where it works. The default is the whole window; a per-screen binding names its screen.

spacr.qt.shortcuts.discover(window) → List[ShortcutSpec][source]

Every shortcut LIVE on window, whether declared or not.

The declared table is what the map is drawn from, because a per-screen binding does not exist until that screen is built and the map has to describe it anyway. This is the other half: a shortcut added at runtime – a plugin, a menu action – appears without anyone editing a list.

Anything already in SHORTCUTS is left to its declaration, which is where the label and the scope live.

Parameters:

window – the widget whose child QShortcut and QAction objects are searched; a widget that cannot be searched yields an empty list.

spacr.qt.shortcuts.install(window: PySide6.QtWidgets.QMainWindow) → None[source]

Wire every shortcut in SHORTCUTS onto window.

Idempotent — safe to call from within reload paths.

Parameters:

window – the main window the application shortcuts are bound to.

spacr.qt.shortcuts.installed() → List[ShortcutSpec][source]

The window-wide keys that install() is responsible for binding.

Gestures are not among them. A gesture is a modifier held while the mouse wheel turns, and it is caught by an event filter rather than by a key sequence, so no shortcut object can express it and none is created for it. Listing one here would promise a binding that cannot be made.

Every gesture is still listed on the shortcut map. mapped() returns what the hands can do, and this returns what the shortcut objects own.

spacr.qt.shortcuts.mapped() → List[ShortcutSpec][source]

Every shortcut the map describes: window-wide, then per-screen.

spacr.qt.shortcuts.native(keys: str) → str[source]

keys in the spelling the user’s own keyboard has.

Ctrl is the Command symbol on macOS and Qt already knows; writing “Ctrl+H” into a label hard-codes one platform into the help.

Parameters:

keys – a key sequence in Qt’s portable spelling, such as 'Ctrl+H'. Returned unchanged when Qt cannot convert it.

spacr.qt.shortcuts.show_cheat_sheet(parent) → None[source]

Show every registered shortcut, grouped by category.

An overlay when parent is a real window, so ? answers and gets out of the way. A modal dialog remains the fallback for a parentless or zero-sized caller, where an overlay would have nothing to cover.

Parameters:

parent – the window to cover. A QWidget with a non-zero size gets the overlay, replacing any overlay it already has; anything else gets a modal dialog parented to it.