Can Maya tools activate temporary shortcuts? Similar to how the sculpting tools work in Maya?

Hey TA.org,

I’ve been looking into tool contexts via the api MpxToolCommand as well as draggerContext in maya cmds. It seems at best there are ctrl and shirt MEvents (in the API) as well as mouse button presses.

Is it possible to have a tool that, when active, reassigns the behavior of the q w e r t y keys? Or other keyboard keys?

For example in Maya, when sculpt mode is active, ctrl 1 2 3 - 9 activate brushes. That kind of temporary “hotkey mapping” is what I’m after. Is this possible in the API?

There is a cmds.hotkey() which might be the simplest option-
When you enter your toolContext or however you begin your tool, for each temp key you want to assign, make a record of its existing command, overwrite with your new one, and then on tool exit, reset it.

1 Like

Thanks @EdArt
I was thinking about it and that might work! As long as I disable autosave flag, even if the user exists Maya without exiting the tool their hotkeys should be preserved. Much thanks.

Using the API, you can replicate the way that sculpt mode works with the number keys using MPxContext. The caveat of this is that MPxContext can only get numerical key and mouse move / click events, so if you want to use other hotkeys you can’t do it with MPxContext.

Some words of warning:

  • If you’re creating a tool context with an API plugin, don’t mix the code with cmds.hotkey unless the hotkey is simply calling a custom tool command and nothing more. Use one or the other or things get real messy, real fast
  • Binding keyboard commands contextually can be confusing for many people because most tools in Maya don’t work like that, save for things like the node editor or script editor
  • You can accidentally royally F up peoples’ keymap using cmds.hotkey

About cmds.hotkey

  • The hotkeys you set will be saved and will still be there when you reopen
  • It will shadow a user’s existing hotkeys and the hotkey editor won’t reflect this; It will still show the original binding ( unless you create a name command using cmds.nameCommand )
  • Unsetting the hotkey doesn’t get rid of the “showing” of the user’s original hotkey
  • I have had some horrible experiences and messed up a user’s keymap trying to do what you’re asking about. They didn’t have their hotkeys saved.

Okay, now that that’s out of the way so let’s talk about some ways that you can make contextual hotkeys.

In my experience, cmds.hotkey works best when you’re using it to bind to global commands that aren’t expected to change during normal use of the app. If you use cmds.hotkey, be sure to create a name command first using cmds.nameCommand, then bind to that so the binding shows up in the hotkey editor and the user can unbind it if something goes wrong. Maya also provides a utility for setting keys contextually using the cmds.hotkeyCtx command in conjunction with the ctxClient argument of cmds.hotkey. I personally haven’t used ctxClient so I can’t speak much on its reliability but you could look into it if you’re interested.

Another way to do contextual hotkeys is using PySide / PySide2’s QShortcut and QShortcutContext. This is far easier to deal with than cmds.hotkey (and much more reliable in my opinion). The only real drawback is that your contextual hotkeys won’t show up in the hotkey editor, but they also won’t get saved and loaded automatically when you reopen Maya either. There’s a blog post on how to set up a contextual QShortcut in Maya here. It’s slightly hacky given that they aren’t attaching the QShortcut to a GUI tool but there’s not much way around that.

All this being said, if you can get by with only using the number keys and not alphabetical keys to set up your contextual keymap then the absolute best method to use is to use the one that Maya provides and expects you to use, and that would be making your own MPxContext.

4 Likes

Thanks for the detailed explanation JoDaRober!

Yeah I was def. concerned about messing up a users key map. I specifically don’t want to save anything. Did you run into problems with cmds.Hotkey with the autoSave flag set to False?

Yeah what I’m after is hotkeys that only activate when a certain tool is active, then deactivate when the tool is exited. (This can def. leave key maps stuck if the tool errors out)

Certain to how modals work in Blender or Vi/Vim. Closest thing would be maya contexts I think.

I’ll look into PyQt, but most likely I’ll just end up with a MPXContext with tool activated, with modifier key triggered, marking menus to switch between settings, similar to how all Mayas tools work (insert edge loop, connect, bevel, multicut, quaddraw) etc.

That gives me ctrl, shift, ctrl+shift, and combos with rmb, mmb, lmb plus 1-0 keys?! That should be plenty I think.

1 Like

I didn’t have much luck with the autoSave flag, it seemed like it didn’t do anything when I tested it. Maybe it doesn’t work how I’m expecting it to though.

The main thing is that cmds.hotkey works best if you define all of your actions ahead of time with name commands, and then when you bind them with cmds.hotkey you want to bind them with a specific context. That way all of the hotkeys are defined once and all you have to do is change the context using cmds.hotkeyCtx, rather than try to do some craziness where you set / unset hotkeys every time the context changes. That’s where you start running into issues. Sorry if I’m being a bit pedantic here.

I’m not meaning to dissuade you from using cmds.hotkey, just letting you know (to hopefully save you a headache) that in my experience it’s not worked exactly in the way I expected it to.

1 Like

These are super helpful to know about, thanks a ton. I had no idea you could set up shortcuts in maya’s own qt application. The QShortcut method seems the most attractive to me (I’m not bothered about keeping the hotkey editor visually in sync with tools).
I wonder though, if a user has a custom Maya hotkey set (eg bring up the translation tool with J instead of W), and a QShortcut is made by an external tool, also using the J key, will both commands be fired?
I guess the only way to avoid that would be to use the full nameCommand / hotKeyCtx system.

1 Like

Def. not pedantic @JoDaRober , all your insights are much appreciated!

1 Like

@EdArt The QShortcut will take precedence over any native Maya hotkeys, depending on how you set the ShortcutContext. The available options are here.

Qt::WidgetShortcut, for example, will only enable the shortcut when its parent widget has focus, much like the way text fields consume all keyboard input when you click inside of them. You can also enable a shortcut when its parent window has focus with Qt::WindowShortcut, or enable it for the entire application, regardless of what has focus with Qt::ApplicationShortcut.

In general, used inputs are consumed, so that means if the keyboard input is handled by a shortcut or a widget, then it will be consumed before maya hears about it. If those shortcuts / widgets don’t consume the input, then it will continue up the chain to let other widgets handle it. Nothing will be called twice

2 Likes