首页 > 解决方案 > 如何在 Gtk3 中检查 CTRL+s?

问题描述

如何检查某个键是否与Gtk3中的特定修饰符一起按下?例如,这里我想检查是否CTRL+s被按下:

use feature qw(say);
use strict;
use warnings;
use Gtk3 '-init';
use Glib qw(TRUE FALSE);

my $window = Gtk3::Window->new('toplevel');
$window->set_title('Hello world');
$window->set_position('center');
$window->set_default_size(500, 500);
$window->signal_connect('delete-event' => sub {
    Gtk3->main_quit();
});
$window->signal_connect('key-press-event' => sub { handle_key( @_ ) } );
$window->show_all();
Gtk3->main();

sub handle_key {
    my ( $widget, $event) = @_;

    my $key = Gtk3::Gdk::keyval_name( $event->keyval );
    if ( ($key eq 's') && control_pressed( $event ) ) {
        say "CTRL+S";
    }
    return FALSE; # FALSE -> means propagate key further
}

我应该如何定义control_pressed()上面的函数?

标签: perlgtk3

解决方案


$event->stateis 属于Gtk3::Gdk::ModifierType具有重载运算符的类型。

标志以重载运算符的形式具有一些额外的魔法能力:

+ or |   union of two flagsets ("add")
-        difference of two flagsets ("sub", "remove")   
* or &   intersection of two bitsets ("and")   
/ or ^   symmetric difference ("xor", you will rarely need this)
>=       contains-operator ("is the left set a superset of the right set?")
==       equality

此外,布尔上下文中的标志指示它们是否为空,这使您可以自然地编写常用操作:

$widget->set_events ($widget->get_events - "motion_notify_mask");  
$widget->set_events ($widget->get_events - ["motion_notify_mask",
                                          "button_press_mask"]);

# shift pressed (both work, it's a matter of taste)   
if ($event->state >= "shift-mask") { ...   
if ($event->state * "shift-mask") { ...

# either shift OR control pressed?   
if ($event->state * ["shift-mask", "control-mask"]) { ...

# both shift AND control pressed?
if ($event->state >= ["shift-mask", "control-mask"]) { ...

此外,GdkModifierType 枚举的常量在 Perl 中变为小写字符串。所以以下应该工作:

sub control_pressed {
    my ( $event ) = @_;

    return $event->state & 'control-mask';
}

推荐阅读