Re: trying to get keypresses in an OptionMenu

Travis J.I. Corcoran said:

I've got an OptionMenu that is unwieldy to scroll through - it has
approximately 2,000 choices.

Menus are not a good UI element for that many choices.  Even a set of 50
elements is stretching the limits of what a menu is good for.  Try using a
scrollable list; gtk+'s TreeView has type-ahead find built in.

The problem I have is that I don't know how to get the
'key-press-event' signal to reach the menu object.

There are a few problems here; you talk about getting the key-press-event to
reach the menu object, then show code connecting to signals on the OptionMenu.
 The OptionMenu is *not* the Menu, it's a button that pops up a Menu.  In
fact, the OptionMenu *does* take key-press-event by default --- that's how
keyboard focus and accessibility stuff works.  (Try pressing space when the
keyboard focus is on the OptionMenu.)

If you want to get the key-press-event on the Menu, you have to connect it to
the Menu.  This, too, works.

  #!/usr/bin/perl -w

  use strict;
  use Gtk2 -init;

  my $window = Gtk2::Window->new;
  $window->signal_connect (destroy => sub { Gtk2->main_quit });
  $window->set_border_width (15);

  my $menu = Gtk2::Menu->new;
  foreach (1..26) {
        my $str = chr(ord('a')-1+$_);
        my $item = Gtk2::MenuItem->new_with_label ($str);
        $menu->append ($item);
        $item->signal_connect (activate => sub { print "$str\n"; });
        $menu->{map}{$str} = $item;
  my $option = Gtk2::OptionMenu->new;
  $option->set_menu ($menu);
  $window->add ($option);

  $option->signal_connect (event => \&describe_event);
  $menu->signal_connect (event => \&describe_event);

  # dirty little trick.
  $menu->signal_connect (key_press_event => sub {
        my ($menu, $event) = @_;
        my $str = Gtk2::Gdk->keyval_name ($event->keyval);
        if (exists $menu->{map}{$str}) {
                $menu->select_item ($menu->{map}{$str});
                return 1;
        return 0;


  sub describe_event {
        my $event = $_[1];
        print  ref($_[0]).": ";
        printf "event->type = %-20s  ", $event->type;
        printf "val = %-5s", Gtk2::Gdk->keyval_name ($event->keyval)
                if $event->type eq 'key-press'
                or $event->type eq 'key-release';
        print "\n";


muppet <scott at asofyet dot org>

[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]