Vista general

Siempre que presiona o suelta una tecla, se emite un evento. Puede conectar un manejador de señales para manejar tales eventos.

Para recibir los eventos del teclado, primero debe llamar a la función Gtk::Widget::add_events() con una máscara de bits de los eventos en los que esté interesado. El manejador de señales de eventos recibirá un argumento que dependerá del tipo de evento. Para eventos del teclado, es un GdkEventKey*. Como de describe en el apéndice, el manejador de señales de eventos devuelve un valor bool para indicar que se maneja completamente la señal (true) o permitir la propagación del evento (false).

Para determinar qué tecla se presionó o soltó, lea el valor de GdkEventKey::keyval y compárelo con una constante en el archivo de cabecera <gdk/gdkkeysyms.h>. Los estados de las teclas modificadoras (mayús, control, etc.) están disponibles como banderas de bits en GdkEventKey::state.

Un ejemplo sencillo:

bool on_key_press_or_release_event(GdkEventKey* event)
{
  if (event->type == GDK_KEY_PRESS &&
    event->keyval == GDK_KEY_1 &&
    (event->state & (GDK_SHIFT_MASK | GDK_CONTROL_MASK | GDK_MOD1_MASK)) == GDK_MOD1_MASK)
  {
    handle_alt_1_press(); // GDK_MOD1_MASK is normally the Alt key
    return true;
  }
  return false;
}

Gtk::Entry m_entry; // in a class definition

// in the class constructor
m_entry.signal_key_press_event().connect( sigc::ptr_fun(&on_key_press_or_release_event) );
m_entry.signal_key_release_event().connect( sigc::ptr_fun(&on_key_press_or_release_event) );
m_entry.add_events(Gdk::KEY_PRESS_MASK | Gdk::KEY_RELEASE_MASK);

23.1.1. Ejemplo

En este ejemplo hay tres combinaciones de teclas: Alt+1 selecciona el primer botón de radio, Alt+2 selecciona el segundo, y la tecla Escape oculta (cierra) la ventana. El manejador de eventos predeterminado se sobrecarga, como se describe en la sección Sobrecargar los manejadores de señales predeterminados en el apéndice.

Figura 23-1Eventos del teclado: simple

Código fuente

File: examplewindow.h (For use with gtkmm 3, not gtkmm 2)

#ifndef GTKMM_EXAMPLEWINDOW_H
#define GTKMM_EXAMPLEWINDOW_H

#include <gtkmm.h>

class ExampleWindow : public Gtk::Window
{
public:

  ExampleWindow();
  virtual ~ExampleWindow();

private:
  //Override default signal handler:
  virtual bool on_key_press_event(GdkEventKey* event);

  Gtk::Grid m_container;
  Gtk::RadioButton m_first;
  Gtk::RadioButton m_second;
};

#endif //GTKMM_EXAMPLEWINDOW_H

File: examplewindow.cc (For use with gtkmm 3, not gtkmm 2)

#include "examplewindow.h"

ExampleWindow::ExampleWindow()
{
  set_title("Keyboard Events");
  set_border_width(10);
  add(m_container);
  
  // Radio buttons:
  m_first.set_label("First");
  m_second.set_label("Second");

  Gtk::RadioButton::Group group = m_first.get_group();
  m_second.set_group(group);
  m_first.set_active();

  // Main Container:
  m_container.add(m_first);
  m_container.add(m_second);

  // Events.
  // We override the default event signal handler.
  add_events(Gdk::KEY_PRESS_MASK);

  show_all_children();
}

bool ExampleWindow::on_key_press_event(GdkEventKey* event)
{
  //GDK_MOD1_MASK -> the 'alt' key(mask)
  //GDK_KEY_1 -> the '1' key
  //GDK_KEY_2 -> the '2' key

  //select the first radio button, when we press alt + 1
  if((event->keyval == GDK_KEY_1) &&
    (event->state &(GDK_SHIFT_MASK | GDK_CONTROL_MASK | GDK_MOD1_MASK)) == GDK_MOD1_MASK)
  {
    m_first.set_active();
    //returning true, cancels the propagation of the event
    return true;
  }
  else if((event->keyval == GDK_KEY_2) &&
    (event->state & (GDK_SHIFT_MASK | GDK_CONTROL_MASK | GDK_MOD1_MASK)) == GDK_MOD1_MASK)
  {
    //and the second radio button, when we press alt + 2
    m_second.set_active();
    return true;
  }
  else if(event->keyval == GDK_KEY_Escape)
  {
    //close the window, when the 'esc' key is pressed
    hide();
    return true;
  }

  //if the event has not been handled, call the base class
  return Gtk::Window::on_key_press_event(event);
}

ExampleWindow::~ExampleWindow()
{
}

File: main.cc (For use with gtkmm 3, not gtkmm 2)

#include "examplewindow.h"
#include <gtkmm/application.h>

int main(int argc, char *argv[])
{
  Glib::RefPtr<Gtk::Application> app = Gtk::Application::create(argc, argv, "org.gtkmm.example");

  ExampleWindow window;

  //Shows the window and returns when it is closed.
  return app->run(window);
}