Shortcuts and keys already assigned somewhere else?

Having odd issues with keyboard shortcuts (again). I have code set up like in the script repository:

shortcuts = [
  ('p', lambda: hh_select_paint()),
  ('[', lambda: hh_select_erase()),
  (']', lambda: hh_select_scissors()),
  ('\\', lambda: hh_select_islands()),
  (';', lambda: hh_place_fiducial()),
  ('s', lambda: toggleSphereBrush()),
  ('`', lambda: cycleEffect(1)),
  ('~', lambda: cycleEffect(-1)),
  ('Ctrl+m', lambda: slicer.util.selectModule('Models')),
  ('S', lambda: slicer.util.selectModule('SegmentEditor')),
  ('U', lambda: slicer.util.selectModule('Markups')),
  ('D', lambda: slicer.util.selectModule('Data')),
]

for (shortcutKey, callback) in shortcuts:
    shortcut = qt.QShortcut(slicer.util.mainWindow())
    shortcut.setKey(qt.QKeySequence(shortcutKey))
    shortcut.connect( 'activated()', callback)

I’ve put debug prints in my various functions to do stuff (toggleSphereBrush()) and they don’t get executed, but interestingly, the backtick and tilde shortcuts do work.

If I reassign backtick or tilde to my functions, my functions get called.

Are those other keys getting caught somewhere else?

THANKS!!

These are from SlicerMorphPrefs (Application Settings->Preferences->SlicerMorph). You may want to disable that first for your tests.

Hey Murat! Hope you’re well.

Yep, that’s why I used them for testing - I know they work for SlicerMorph! Just wondering why the others don’t work.

Thanks!!

Most of these shortcuts work for me (except the S and s, which you broke for yourself by redefining).

Try these:

shortcuts = [
  ('p', lambda: print('pressed: p')),
  ('z', lambda: print('pressed: z')),
  ('q', lambda: print('pressed: q')),
  ('f', lambda: print('pressed: f')),
  ('[', lambda: print('pressed: [')),
  (']', lambda: print('pressed: ]')),
  ('\\', lambda: print('pressed: \\')),
  (';', lambda: print('pressed: ;')),
  ('`', lambda: print('pressed: `')),
  ('~', lambda: print('pressed: ~')),
  ('Ctrl+m', lambda: print('pressed: Ctrl-m')),
  ('S', lambda: print('pressed: S')),
  ('O', lambda: print('pressed: O')),
  ('U', lambda: print('pressed: U')),
  ('D', lambda: print('pressed: D')),
]

for (shortcutKey, callback) in shortcuts:
    shortcut = qt.QShortcut(slicer.util.mainWindow())
    shortcut.setKey(qt.QKeySequence(shortcutKey))
    shortcut.connect( 'activated()', callback)

If you or someone else adds a shortcut with the same key sequence then effectively breaks all actions, as the shortcut will no longer emit activated() signal but activatedAmbiguously().

Unfortunately, I don’t know an easy way to determine where each shortcut comes from where, other than search in the source code of all installed extensions for shortcut.

Extensions should not install any keyboard shortcut by default (without explicitly approved by the user). Also, if any shortcut is added then a meaningful objectName should be set, for example containing the name of the extension and module, to make it easier to detect and resolve conflicts by turning off irrelevant shortcuts.

Gaaaah, I should have realized ‘S’ and ‘s’ could be interpreted by Qt as the same keypress - I probably should have used Qt::Shift modifiers or whatever they are to be more explicit.

Thanks!