Vista general

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

The event signal handler will receive an argument that depends on the type of event. For keyboard events it's a GdkEventKey*. As discribed in the appendix, the event signal handler returns a bool value, to indicate that the signal is fully handled (true) or allow event propagation (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.

Here's a simple example:

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) );

21.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 gestor de eventos predeterminado se sobrecarga, como se describe en la sección Sobrecargar los gestores de señales predeterminados en el apéndice.

Figura 21-1Eventos del teclado: simple

Source Code

File: examplewindow.h (For use with gtkmm 4)

#ifndef GTKMM_EXAMPLEWINDOW_H
#define GTKMM_EXAMPLEWINDOW_H

#include <gtkmm.h>

class ExampleWindow : public Gtk::Window
{
public:

  ExampleWindow();
  virtual ~ExampleWindow();

private:
  // Signal handler:
  bool on_window_key_pressed(guint keyval, guint keycode, Gdk::ModifierType state);

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

#endif //GTKMM_EXAMPLEWINDOW_H

File: main.cc (For use with gtkmm 4)

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

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

  ExampleWindow window;

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

File: examplewindow.cc (For use with gtkmm 4)

#include "examplewindow.h"

ExampleWindow::ExampleWindow()
{
  set_title("Keyboard Events");
  m_container.set_margin(10);
  add(m_container);

  // Radio buttons:
  m_first.set_label("First");
  m_second.set_label("Second");

  m_second.join_group(m_first);
  m_first.set_active();

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

  // Events.
  auto controller = Gtk::EventControllerKey::create();
  controller->signal_key_pressed().connect(
    sigc::mem_fun(*this, &ExampleWindow::on_window_key_pressed), false);
  add_controller(controller);
}

bool ExampleWindow::on_window_key_pressed(guint keyval, guint, Gdk::ModifierType state)
{
  //Gdk::ModifierType::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((keyval == GDK_KEY_1) &&
    (state & (Gdk::ModifierType::SHIFT_MASK | Gdk::ModifierType::CONTROL_MASK | Gdk::ModifierType::MOD1_MASK)) == Gdk::ModifierType::MOD1_MASK)
  {
    m_first.set_active();
    //returning true, cancels the propagation of the event
    return true;
  }
  else if((keyval == GDK_KEY_2) &&
    (state & (Gdk::ModifierType::SHIFT_MASK | Gdk::ModifierType::CONTROL_MASK | Gdk::ModifierType::MOD1_MASK)) == Gdk::ModifierType::MOD1_MASK)
  {
    //and the second radio button, when we press alt + 2
    m_second.set_active();
    return true;
  }
  else if(keyval == GDK_KEY_Escape)
  {
    //close the window, when the 'esc' key is pressed
    hide();
    return true;
  }

  //the event has not been handled
  return false;
}

ExampleWindow::~ExampleWindow()
{
}