The simplest way to get an event handler called on a key press is to connect the handler to the key-press-event
signal. In this example, we register for the event for the whole window, but you can also register for individual widgets too.
The most important part is the connection of the handler to the event:
self.connect("key-press-event",self.on_key_press_event)
In the event handler, the widget and the key-press event are passed in as parameters. Key-press modifiers such as the Ctrl key are available in event.state
and the pressed key is event.keyval
.
Values for modifier keys are found in Gdk.ModiferType
and include CONTROL_MASK
, SHIFT_MASK
and several others.
Key values are found in Gdk
with prefixes of KEY_
, for example, the h key is Gdk.KEY_h
) These can be converted to a string using Gdk.keyval_name()
.
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk
from gi.repository import Gdk
class MyWindow(Gtk.Window):
key = Gdk.KEY_h
def __init__(self):
# init the base class (Gtk.Window)
super().__init__()
# state affected by shortcuts
self.shortcut_hits = 0
# Tell Gtk what to do when the window is closed (in this case quit the main loop)
self.connect("delete-event", Gtk.main_quit)
# connect the key-press event - this will call the keypress
# handler when any key is pressed
self.connect("key-press-event",self.on_key_press_event)
# Window content goes in a vertical box
box = Gtk.VBox()
# mapping between Gdk.KEY_h and a string
keyname = Gdk.keyval_name(self.key)
# a helpful label
instruct = Gtk.Label(label="Press Ctrl+%s" % keyname)
box.add(instruct)
# the label that will respond to the event
self.label = Gtk.Label(label="")
self.update_label_text()
# Add the label to the window
box.add(self.label)
self.add(box)
def on_key_press_event(self, widget, event):
print("Key press on widget: ", widget)
print(" Modifiers: ", event.state)
print(" Key val, name: ", event.keyval, Gdk.keyval_name(event.keyval))
# check the event modifiers (can also use SHIFTMASK, etc)
ctrl = (event.state & Gdk.ModifierType.CONTROL_MASK)
# see if we recognise a keypress
if ctrl and event.keyval == Gdk.KEY_h:
self.shortcut_hits += 1
self.update_label_text()
def update_label_text(self):
# Update the label based on the state of the hit variable
self.label.set_text("Shortcut pressed %d times" % self.shortcut_hits)
if __name__ == "__main__":
win = MyWindow()
win.show_all()
# Start the Gtk main loop
Gtk.main()
More advanced behaviour for application-wide shortcuts can be achieved with an accelerator group (Gtk.AccelGroup
), but often a quick key-press handler is all you need to capture the keyboard events you want for a specific widget.