Как получить состояние ключа в Perl/Tk?
В Perl/Tk возможно связать событие следующим образом:
$mw->bind('<KeyPress-W>', sub{print "W is pressed";});
Можно ли получить эту информацию в другом направлении? Могу ли я сделать звонок типа "получить статус клавиши" или "проверить, нажата ли W"?
Это не будет реагировать непосредственно на событие.
Конечно, есть возможность заполнять переменные для различных событий, но я хочу знать, есть ли такой метод.
1 ответ
Perl/Tk не предоставляет такой функциональности. Так что вам придется отслеживать события самостоятельно. Обратите внимание, что есть Any-KeyPress
а также Any-KeyRelease
события, поэтому вам не нужно создавать привязку для каждого ключа:
$mw->bind("<Any-KeyPress>" => sub {
warn $_[0]->XEvent->K; # prints keysym
});
Если вы на X11, то с помощью X11::Protocol
модуль (который может использоваться в скрипте Perl/Tk) и вызов QueryKeymap
Метод даст вам фактически нажатые коды клавиш. Вот небольшой скрипт, который демонстрирует это:
use strict;
use X11::Protocol;
# Get the keycode-to-keysym mapping. Being lazy, I just parse
# the output of xmodmap -pke. The "real" approach would be to
# use X11 functions like GetKeyboardMapping() and the
# X11::Keysyms module.
my %keycode_to_keysym;
{
open my $fh, "-|", "xmodmap", "-pke" or die $!;
while(<$fh>) {
chomp;
if (m{^keycode\s+(\d+)\s*=(?:\s*(\S+))?}) {
if (defined $2) {
$keycode_to_keysym{$1} = $2;
}
} else {
warn "Cannot parse $_";
}
}
}
my $x11 = X11::Protocol->new;
while(1) {
my $keyvec = $x11->QueryKeymap;
for my $bit (0 .. 32*8-1) {
if (vec $keyvec, $bit, 1) {
warn "Active key: keycode $bit, keysym $keycode_to_keysym{$bit}\n";
}
}
sleep 1;
}