Přehled

Kdykoliv zmáčknete nebo uvolníte klávesu, je vyslána událost. Můžete se napojit na obsluhu signálu a takovéto události zpracovávat.

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

Pro určení, která klávesa byl zmáčknuta nebo uvolněna, můžete číst hodnotu GdkEventKey::keyval a porovnat ji s konstantou v hlavičkovém souboru <gdk/gdkkeysyms.h>. Stav modifikačních kláves (Shift, Ctrl, atd.) je dostupný v podobě bitových příznaků v 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. Příklad

V tomto příkladu jsou tři klávesové zkratky: Alt+1 vybírá první skupinový přepínač, Alt+2 vybírá druhý a klávesa Esc skryje (zavře) okno. Výchozí obsluha signálu události je přepsaná tak, jak je popsáno v oddílu Přepisování výchozí obsluhy signálu v dodatku.

Obrázek 21-1Události klávesnice – jednoduchý příklad

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::Box m_container;
  Gtk::CheckButton m_first;
  Gtk::CheckButton 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");

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

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

#include "examplewindow.h"

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

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

  m_second.set_group(m_first);
  m_first.set_active();

  // Main Container:
  m_container.set_orientation(Gtk::Orientation::HORIZONTAL);
  m_container.append(m_first);
  m_container.append(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::ALT_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::ALT_MASK)) == Gdk::ModifierType::ALT_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::ALT_MASK)) == Gdk::ModifierType::ALT_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()
{
}