Get Key Combinations

Get key combinations


@Override
public void keyPressed(KeyEvent evt) {
if (evt.getKeyCode()==KeyEvent.VK_CONTROL) { ctrl = true; }
else if (evt.getKeyCode()==KeyEvent.VK_SHIFT) { shift = true; }
else if (evt.getKeyCode()==KeyEvent.VK_ALT) { alt = true; }
else {
keyHit = KeyEvent.getKeyText( evt.getKeyCode() );
System.out.println("Key Hit is "+keyHit);
}

processLocalKeyEvent(evt);
}

@Override
public void keyReleased(KeyEvent evt) {

if (evt.isControlDown() && keyHit != "") ctrl = true;
if (evt.isAltDown() && keyHit != "") alt = true;
if (evt.isShiftDown() && keyHit != "") shift = true;

if (ctrl) sb.append("Ctrl");
if (shift) sb.append("Shift");
if (alt) sb.append("Alt");
if (!ctrl && !shift && !alt) {
sb.append(keyHit);
} else {
sb.append("_"+keyHit);
}

if (ctrl || shift || alt) {
Thread thread = new Thread();
try {
thread.sleep(300);
rfbProto.capture();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} else if ((ctrl || shift || alt) && keyHit=="") {
rfbProto.capture();
} else if ((!ctrl || !shift || !alt) && keyHit!="") {
rfbProto.capture();
}

ctrl = false;
shift = false;
alt = false;
keyHit = "";
sb = new StringBuffer();
processLocalKeyEvent(evt);
}

How can i detect key combinations in Windows python3+?

so there's a super simple library called keyboard

Install it with pip install keyboard

import keyboard

if keyboard.is_pressed('ctrl+v'):
# Call your function

I hope that I helped you.

How to listen for regular keys and key combinations in Python

sort of rewrite the pynput sample code so that the program can monitor combination of shift key.

I made a global variable SHIFT_STATE to record if the shift key is pressed, and I believe you can expand this to monitor ctrl, alt, cmd keys and make the code looks prettier.

By the way, the library has the power to monitor global-hotkeys
however I did not look into it too much. You can check it out here: https://pynput.readthedocs.io/en/latest/keyboard.html#global-hotkeys

from pynput import keyboard

SHIFT_STATE = False
def on_press(key):
global SHIFT_STATE
if key == keyboard.Key.shift:
SHIFT_STATE = True
else:
try:
if SHIFT_STATE:
print(f'shift + {key}')
else:
print(key)
except Exception as e:
print(e)

def on_release(key):
global SHIFT_STATE
if key == keyboard.Key.esc:
# Stop listener
return False
elif key == keyboard.Key.shift:
SHIFT_STATE = False

# Collect events until released
with keyboard.Listener(
on_press=on_press,
on_release=on_release) as listener:
listener.join()

and here's the screenshot I ran the code FYI
pynput rewrite

Capturing ctrl+z key combination in javascript


  1. Use onkeydown (or onkeyup), not onkeypress
  2. Use keyCode 90, not 122
function KeyPress(e) {
var evtobj = window.event? event : e
if (evtobj.keyCode == 90 && evtobj.ctrlKey) alert("Ctrl+z");
}

document.onkeydown = KeyPress;

Online demo: http://jsfiddle.net/29sVC/

To clarify, keycodes are not the same as character codes.

Character codes are for text (they differ depending on the encoding, but in a lot of cases 0-127 remain ASCII codes). Key codes map to keys on a keyboard. For example, in unicode character 0x22909 means 好. There aren't many keyboards (if any) who actually have a key for this.

The OS takes care of transforming keystrokes to character codes using the input methods that the user configured. The results are sent to the keypress event. (Whereas keydown and keyup respond to the user pressing buttons, not typing text.)

Detect only a specific Keyboard combination in Unity


Event.current and OnGUI

Though usually it is not used so often anymore you can check the input in OnGUI using Event.current.

Every time a key goes down, store it in a list of currently pressed keys. When this keys goes up remove it from the list. Then you can simply check if the list contains the according keys and if the length matches the expected key amount.

public HashSet<KeyCode> currentlyPressedKeys = new HashSet<KeyCode>();

private void OnGUI()
{
if (!Event.current.isKey) return;

if (Event.current.keyCode != KeyCode.None)
{
if (Event.current.type == EventType.KeyDown)
{
currentlyPressedKeys.Add(Event.current.keyCode);
}
else if (Event.current.type == EventType.KeyUp)
{
currentlyPressedKeys.Remove(Event.current.keyCode);
}
}

// Shift is actually the only Key which is not treated as a
// EventType.KeyDown or EventType.KeyUp so it has to be checked separately
// You will not be able to check which of the shift keys is pressed!
if (!Event.current.shift)
{
return;
}

// As said shift is check on another way so we want only
// exactly 1 key which is KeyCode.B
if (currentlyPressedKeys.Count == 1 && currentlyPressedKeys.Contains(KeyCode.B))
Debug.Log("Only Shift + B");
}

It has to be done in OnGUI since there might be multiple events in one single frame. This is exclusive and will ony fire while Shift + B is pressed.

If you rather put this somewhere in your scene and make the values static

public class KeysManager : MonoBehaviour
{
public static bool ShiftPressed;
public static HashSet<KeyCode> currentlyPressedKeys = new HashSet<KeyCode>();

private void OnGUI()
{
if (!Event.current.isKey) return;

if (Event.current.keyCode != KeyCode.None)
{
if (Event.current.type == EventType.KeyDown)
{
currentlyPressedKeys.Add(Event.current.keyCode);
}
else if (Event.current.type == EventType.KeyUp)
{
currentlyPressedKeys.Remove(Event.current.keyCode);
}
}

ShiftPressed = Event.current.shift;
}
}

Then you can as before use something like

private void Update()
{
if (KeysManager.ShiftPressed && KeysManager.currentlyPressedKeys.Count == 1 && KeysManager.currentlyPressedKeys.Contains(KeyCode.B))
{
Debug.Log("Only Shift + B exclusively should trigger this");
}
}

Iterating with Input.GetKey through all KeyCode

Alternatively you could as commented check all possible keys.

However, this might or might not be an issue regarding performance. You'll have to test that and decide whether it is acceptable in your specific case.

using System.Linq;

...

// will store all buttons except B and LeftShift
KeyCode[] otherKeys;

private void Awake ()
{
// This simply returns an array with all values of KeyCode
var allKeys = (KeyCode[])Enum.GetValues(typeof(KeyCode));

// This uses Linq Where in order to only keep entries that are different from
// KeyCode.B and KeyCode.LeftShift
// ToArray finally converts the IEnumerable<KeyCode> into a KeyCode[]
otherKeys = allKeys.Where(k => k != KeyCode.B && k != KeyCode.LeftShift).ToArray();
}

private void Update()
{
if(Input.GetKey(KeyCode.LeftShift) && Input.GetKey(KeyCode.B) && !AnyOtherKeyPressed())
{
// Happens while ONLY LeftShift + B is pressed
}
}

// Return true if any other key
// is pressed except B and LeftShift
private bool AnyOtherKeyPressed()
{
foreach (var keyCode in otherKeys)
{
if(Input.GetKey(keyCode)) return true;
}

return false;
}

Maybe we worry too much and it doesn't matter (I woudln't believe that but just theoretically ^^) than you could even take it one level up and make it more flexible.

[Serializable]
public class KeyCombo
{
// Note I'll be lazy here .. you could create a custom editor
// for making sure each keyCode is unique .. but another time
public List<KeyCode> keyCodes = new List<KeyCode>();

// This will show an event in the Inspector so you can add callbacks to your keyCombos
// this is the same thing used in e.g. Button onClick
public UnityEvent whilePressed;

// Here all other keyCodes will be stored
[HideInInspector] public KeyCode[] otherKeys;

// Return true if any other key
// is pressed except B and LeftShift
public bool AnyOtherKeyPressed()
{
foreach (var keyCode in otherKeys)
{
if (Input.GetKey(keyCode)) return true;
}

return false;
}
}

public List<KeyCombo> keyCombos = new List<KeyCombo>();

private void Awake()
{
// This simply returns an array with all values of KeyCode
var allKeys = (KeyCode[])Enum.GetValues(typeof(KeyCode));

foreach (var keyCombo in keyCombos)
{
// This uses Linq Where in order to only keep entries that are different from
// the ones listed in keyCodes
// ToArray finally converts the IEnumerable<KeyCode> into a KeyCode[]
keyCombo.otherKeys = allKeys.Where(k => !keyCombo.keyCodes.Contains(k)).ToArray();
}
}

private void Update()
{
foreach (var keyCombo in keyCombos)
{
if (keyCombo.keyCodes.All(Input.GetKey) && !keyCombo.AnyOtherKeyPressed())
{
keyCombo.whilePressed.Invoke();
}
}
}

With this you can now add multiple KeyCombos and check them individually - However be aware that every additional keyCombo also means one additional iteration through all other keys so ... it's far away from perfect.



Related Topics



Leave a reply



Submit