Επισκόπηση

Όποτε πατάτε ή απελευθερώνετε ένα πλήκτρο, εκπέμπεται ένα συμβάν. Μπορείτε να συνδέσετε έναν χειριστή σήματος για να επεξεργαστεί τέτοια συμβάντα.

Για να δεχτείτε τα συμβάντα του πληκτρολογίου, πρέπει πρώτα να; καλέσετε τη συνάρτηση Gtk::Widget::add_events() με λίγη μάσκα των συμβάντων που ενδιαφέρεστε. Το συμβάν χειριστή σήματος θα δεχτεί ένα όρισμα που εξαρτάται από τον τύπο του συμβάντος. Για συμβάντα πληκτρολογίου είναι ένας GdkEventKey*. Όπως περιγράφτηκε στο παράρτημα, ο χειριστής σήματος συμβάντος επιστρέφει μια τιμή Μπουλ, για να δείξει ότι το σήμα επεξεργάστηκε πλήρως (true) ή να επιτρέψει τη διάδοση του συμβάντος (false).

Για να προσδιορίσετε ποιο πλήκτρο πατήθηκε ή απελευθερώθηκε διαβάζετε την τιμή της GdkEventKey::keyval και την συγκρίνετε με μια σταθερά στο αρχείο κεφαλίδας <gdk/gdkkeysyms.h>. Οι καταστάσεις των πλήκτρων τροποποίησης (Shift, Ctrl, κλπ.) είναι διαθέσιμες ως σημαίες δυαδικών ψηφίων στη 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) );
m_entry.add_events(Gdk::KEY_PRESS_MASK | Gdk::KEY_RELEASE_MASK);

23.1.1. Παράδειγμα

Σε αυτό το παράδειγμα υπάρχουν τρεις συντομεύσεις πληκτρολογίου: η Alt+1 επιλέγει το πρώτο ραδιοπλήκτρο, η Alt+2 επιλέγει το δεύτερο και το πλήκτρο Esc κρύβει (κλείνει) το παράθυρο. Ο προεπιλεγμένος χειριστής σήματος αντικαθίσταται, όπως περιγράφεται στην ενότητα Αντικατάσταση προεπιλεγμένων χειριστών σημάτων στο παράρτημα.

Φιγούρα 23-1Συμβάντα πληκτρολογίου - απλό

Source Code

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:
  bool on_key_press_event(GdkEventKey* event) override;

  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* key_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((key_event->keyval == GDK_KEY_1) &&
    (key_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((key_event->keyval == GDK_KEY_2) &&
    (key_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(key_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(key_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[])
{
  auto app = Gtk::Application::create(argc, argv, "org.gtkmm.example");

  ExampleWindow window;

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