Ben L
Ben L

Reputation: 7078

Detect key press combination in Linux with Python?

I'm trying to capture key presses so that when a given combination is pressed I trigger an event.

I've searched around for tips on how to get started and the simplest code snippet I can find is in Python - I grabbed the code below for it from here. However, when I run this from a terminal and hit some keys, after the "Press a key..." statement nothing happens.

Am I being stupid? Can anyone explain why nothing happens, or suggest a better way of achieving this on Linux (any language considered!)?

import Tkinter as tk

def key(event):
    if event.keysym == 'Escape':
        root.destroy()
    print event.char

root = tk.Tk()
print "Press a key (Escape key to exit):"
root.bind_all('<Key>', key)
# don't show the tk window
root.withdraw()
root.mainloop()

Upvotes: 5

Views: 7669

Answers (5)

segalion
segalion

Reputation: 11

tkinter 'bind' method only works when tkinter window is active.

If you want binding keystrokes combinations that works in all desktop (global key/mouse binding) you can use bindglobal (install with pip install bindglobal). It works exactly like standard tkinter 'bind'.

Example code:

import bindglobal
def callback(e):
    print("CALLBACK event=" + str(e))

bg = bindglobal.BindGlobal()
bg.gbind("<Menu-1>",callback)
bg.start()

Upvotes: 0

Ben L
Ben L

Reputation: 7078

Well, turns out there is a much simpler answer when using GNOME which doesn't involve any programming at all...

http://www.captain.at/howto-gnome-custom-hotkey-keyboard-shortcut.php

Archived on Wayback

Just create the script/executable to be triggered by the key combination and point the 'keybinding_commands' entry you create in gconf-editor at it.

Why didn't I think of that earlier?

Upvotes: 1

Ben L
Ben L

Reputation: 7078

Alternatively (a non-Python option) use XBindKeys.

Upvotes: 1

S.Lott
S.Lott

Reputation: 392070

What you're doing is reading /dev/tty in "raw" mode.

Normal Linux input is "cooked" -- backspaces and line endings have been handled for you.

To read a device like your keyboard in "raw" mode, you need to make direct Linux API calls to IOCTL.

Look at http://code.activestate.com/recipes/68397/ for some guidance on this. Yes, the recipe is in tcl, but it gives you a hint as to how to proceed.

Upvotes: 1

Ulf
Ulf

Reputation: 19130

Tk does not seem to get it if you do not display the window. Try:

import Tkinter as tk

def key(event):
    if event.keysym == 'Escape':
        root.destroy()
    print event.char

root = tk.Tk()
print "Press a key (Escape key to exit):"
root.bind_all('<Key>', key)
# don't show the tk window
# root.withdraw()
root.mainloop()

works for me...

Upvotes: 3

Related Questions