[Rio-pm] Tecla pressionada
Marcos Machado
listas em istf.com.br
Terça Março 4 11:50:02 PST 2008
Bom, acabei encontrando algo que me atende bem. O código abaixo mostra a
tecla pressionada e a tecla solta.
Um efeito que não previa é a possibilidade de saber quando uma "tecla
cinza" é pressionada como, por exemplo, o shift, coisa que não é
possível lendo pelo terminal.
Pode parecer óbvio para quem já programou nesse ambiente. Para mim é
tudo novidade. :)
<code>
use Tk;
$top = MainWindow->new();
$frame = $top->Frame( -height => "2c", -width => "2c" );
$frame->pack;
$top->bind("<Any-KeyPress>" =>
sub
{
my $c = shift;
my $e = $c->XEvent;
print "Pressionada = ", $e->K, "$/";
});
$top->bind("<Any-KeyRelease>" =>
sub
{
my $c = shift;
my $e = $c->XEvent;
print "Liberada = ", $e->K, "$/";
});
MainLoop();
</code>
Se quiser testar um evento de "release" de tecla mais longo, execute
antes o comando "xset -r" para desligar a repetição da tecla quando ela
é pressionada por muito tempo.
Obs: Logo percebe-se que Ctrl+C é inútil para encerrar o programa.
Fechar a janelinha que ele abre é o suficiente.
[]s, MM
Fernando Oliveira escreveu:
> será q vc não pode fazer algo parecido com isso?:
> <code>
> use Term::ReadKey;
>
> ReadMode 4;
> while (($key = ReadKey(-1)) ne "q") {for(keys %time){delete $time{$_} if
> time - $time{$_} > $vezes}next unless defined
> $key;$time{$key}=time,$vezes=1 unless defined $time{$key};delete
> @time{grep {$_ ne $key} keys %time}; $vezes++ if time - $time{$key} <=
> $valor;delete $time{$key}, undef $vezes, print "$key foi pressionado por
> 5 segundos$/" if time - $time{$key} == 5}END{ReadMode 0;}
> </code>
>
> Em 19/02/08, *Marcos Machado* <listas em istf.com.br
> <mailto:listas em istf.com.br>> escreveu:
>
> Hmmmm... Obrigado pela luz!
>
> Vou experimentar estas idéias.
>
> O fato de precisar mapear uma tecla específica com um evento é ruim,
> pois não sei o que será pressionado e, em qualquer tecla, a rotina
> executada é a mesma.
>
> Outra coisa que me preocupa é o processamento intrínseco destas
> bibliotecas ou do próprio ambiente. O tempo que a tecla vai ficar
> pressionada é muito, muito pequeno (imagina o tempo que cada tecla fica
> pressionada enquanto você digita um texto) e vai complicar se ficarmos
> muito dependente do processamento da máquina para me dar esse valor.
>
> Mas vou fazer uns testes e volto com o resultado.
>
> []s, MM
>
>
> breno escreveu:
> > Em Mac, seria assim:
> >
> > -----------------8<--------------------
> > use Mac::Events qw(@Event $CurrentEvent);
> >
> > $Event[keyDown] = \&trata_tecla_apertada;
> > $Event[keyUp] = \&trata_tecla_solta;
> > -----------------8<--------------------
> >
> > E no Windows dá pra fazer assim:
> > -----------------8<--------------------
> > use Win32::Console;
> >
> > $CONSOLE = new Win32::Console->new(STD_INPUT_HANDLE);
> >
> > do {
> > @event = $CONSOLE->Input();
> > # [0] : tipo de evento (1 para teclado)
> > # [1] : keydown (TRUE == tecla apertada, FALSE == tecla foi solta)
> > # [2] : número de vezes que o Input retornou a tecla como
> ainda apertada
> > # [3] : virtual key code da tecla
> > # [4] : virtual scan code da tecla
> > # [5] : código ASCII do caractere apertado (ou 0 se nao for
> caractere)
> > # [6] : estado das teclas de controle (CTRL ALT SHIFT)
> >
> > # processa tecla enquanto está apertada
> > ...
> >
> > } while ($event[0] == 1 and $event[1]);
> > -----------------8<--------------------
> >
> > E em SDL:
> > -----------------8<--------------------
> > use SDL::Event;
> >
> > my $event = new SDL::Event;
> > $event->pump;
> > $event->poll;
> >
> > if ( $event->type == SDL::KEYDOWN ) {
> > # tecla pressionada. Pra saber qual tecla, basta adicionar aqui:
> > if ( $event->key_sym == SDLK_ESCAPE ) { # ou qq outra, brincando
> > com key_sym
> > ...
> > }
> > }
> > if ( $event->type == SDL::KEYDOWN ) {
> > # idem
> > }
> > -----------------8<--------------------
> >
> > Mas direto num terminal linux.... não sei =P
> >
> > Provavelmente a obtenção de eventos tipo keydown/keyup esteja
> > disponível amarrada a algum loop de eventos (já que a shell em si é,
> > por padrão, orientada a stream de caracteres e não a eventos). Dentro
> > do X é muito fácil (pois é um ambiente baseado em eventos), e qq
> > biblioteca como Tk, GTK, Wx, ou mesmo acesso X "rawzão" resolve o seu
> > problema. Pra terminal, loops de eventos pré-prontos podem te ajudar
> > em sua saga. Nunca usei POE, mas ele é um que pode ter o que vc quer.
> > E, se não me falha a memória, o Curses também tem (resta saber se a
> > implementação do Curses.pm <http://Curses.pm> está completa em
> relação à bilbioteca, já
> > que a documentação deles foi bem preguiçosa).
> >
> > Não deixe de nos avisar sobre sua solução :-)
> >
> > []s
> >
> > -b
> >
> > 2008/2/19 Marcos Machado <listas em istf.com.br
> <mailto:listas em istf.com.br>>:
> >> Caros monges,
> >>
> >> Estou procurando uma forma de identificar uma tecla pressionada. O
> >> exemplo abaixo me diz, tecla a tecla, o que foi digitado, sem
> precisar
> >> esperar o <Enter>.
> >>
> >> <code>
> >> use Term::ReadKey;
> >> open(TTY, "</dev/tty");
> >> ReadMode "raw";
> >> while (ord $key != 10) # 10 = return/enter
> >> {
> >> $key = ReadKey 0, *TTY;
> >> print "Voce pressionou a tecla $key (",ord $key,")", $/;
> >> }
> >> ReadMode "normal"; # restaura modo normal de leitura
> >> </code>
> >>
> >> Agora gostaria de descobrir por QUANTO TEMPO uma tecla se manteve
> >> pressionada. Este método me tira da linha 6 assim que eu pressiono a
> >> tecla. Preciso de um evento quando a tecla é pressionada e outro
> quando
> >> ela é solta.
> >>
> >> Alguma dica?
> >>
> >> Não precisa ser portável. Funcionando em Linux já tá bom demais.
> >>
> >> Obrigado pela atenção.
> >>
> >> []s, MM
> >> _______________________________________________
> >> Rio-pm mailing list
> >> Rio-pm em pm.org <mailto:Rio-pm em pm.org>
> >> http://mail.pm.org/mailman/listinfo/rio-pm
> >>
> > _______________________________________________
> > Rio-pm mailing list
> > Rio-pm em pm.org <mailto:Rio-pm em pm.org>
> > http://mail.pm.org/mailman/listinfo/rio-pm
> >
>
> _______________________________________________
> Rio-pm mailing list
> Rio-pm em pm.org <mailto:Rio-pm em pm.org>
> http://mail.pm.org/mailman/listinfo/rio-pm
>
>
>
>
> --
> []'s Fernando
>
>
> ------------------------------------------------------------------------
>
> _______________________________________________
> Rio-pm mailing list
> Rio-pm em pm.org
> http://mail.pm.org/mailman/listinfo/rio-pm
Mais detalhes sobre a lista de discussão Rio-pm