[英]Perl Term::ReadKey with Arrow Keys
I'm using Term::ReadKey in ReadMode('cbreak') to read a single character and perform an action based on the input.我在 ReadMode('cbreak') 中使用 Term::ReadKey 读取单个字符并根据输入执行操作。 This works fine for all other keys except the arrow keys.这适用于除箭头键之外的所有其他键。 When the arrow keys are pressed, the action is performed 3 times and I understand this is because the arrow keys translate to '^[[A', etc...当按下箭头键时,该操作执行 3 次,我理解这是因为箭头键转换为 '^[[A' 等...
How do I translate the arrow keys into some arbitrary single value that the ReadKey can interpret?如何将箭头键转换为 ReadKey 可以解释的任意单个值?
I tried the following code but it doesn't work:我尝试了以下代码,但它不起作用:
use Term::ReadKey;
ReadMode('cbreak');
my $keystroke = '';
while ($keystroke ne 'h') {
print "Enter key: ";
#Read user keystroke
$keystroke = ReadKey(0);
chomp($keystroke);
if(ord($keystroke) == 27) {
$keystroke = ('0');
}
}
Here's my code based on the suggestion:这是我基于建议的代码:
use Term::RawInput;
use strict;
use warnings;
my $keystroke = '';
my $special = '';
while(lc($keystroke) ne 'i' && lc($keystroke) ne 't'){
my $promptp = "Enter key: ";
($keystroke,$special) = rawInput($promptp, 1);
if ($keystroke ne '') {
print "You hit the normal '$keystroke' key\n";
} else {
print "You hit the special '$special' key\n";
}
chomp($keystroke);
$keystroke = lc($keystroke);
}
if($keystroke eq 'i') {
#Do something
}
if($keystroke eq 't') {
#Do something
}
Now, no matter what I press, I can't exit this loop现在,无论我按什么,我都无法退出这个循环
Here's the output:这是输出:
Enter key:
Enter key:
Enter key: You hit the normal 't' key
#Proceeds to function
Here's my working solution...这是我的工作解决方案......
use Term::ReadKey;
ReadMode('cbreak');
{
#Temporarily turn off warnings so no messages appear for uninitialized $keystroke
#that for some reason appears for the if statement
no warnings;
my $keystroke = '';
while ($keystroke ne 'h') {
print "\nEnter key: ";
#Read user keystroke
$keystroke = ReadKey(0);
#The first character for the arrow keys (ex. '^[[A') evaluates to 27 so I check for
#that
if(ord($keystroke) == 27) {
#Flush the rest of the characters from input buffer
#This produces an 'Use of uninitialized value...' error
#for the other two characters, hence 'no warnings' at the beginning.
#This will ignore the other 2 characters and only cause a single iteration
while( defined ReadKey(-1) ) {}
}
ReadMode 0;
}
}
Term::RawInput
doesn't cover everything, but it's a pretty good start for this task: Term::RawInput
并未涵盖所有内容,但对于此任务来说,这是一个不错的开始:
use Term::RawInput;
my ($keystroke,$special) = rawInput("", 1);
if ($keystroke ne '') {
print "You hit the normal '$keystroke' key\n";
} else {
print "You hit the special '$special' key\n";
}
If you're wanting to read high-level semantic ideas of "keypresses", rather than lower-level ideas of "bytes from the terminal" you'll need something that can parse and collect up those multi-byte sequences for you.如果您想阅读“按键”的高级语义思想,而不是“来自终端的字节”的低级思想,您将需要一些可以为您解析和收集这些多字节序列的东西。
For this sort of task, I wrote Term::TermKey :对于此类任务,我编写了Term::TermKey :
use Term::TermKey;
my $tk = Term::TermKey->new( \*STDIN );
print "Press any key\n";
$tk->waitkey( my $key );
print "You pressed: " . $tk->format_key( $key, 0 );
Based on mob
answer, using Term::RawInput , I did this script to emulate a more complex input interaction.基于mob
answer,使用Term::RawInput ,我做了这个脚本来模拟更复杂的输入交互。 The most important difference is the use of 'rawInput': mob
suggested: rawInput("",1)
, I find out that actually using rawInput("> ")
(without the second parameter) makes things easier to work with, and having a prompt ">" is more useful.最重要的区别是使用 'rawInput': mob
rawInput("",1)
: rawInput("",1)
,我发现实际上使用rawInput("> ")
(没有第二个参数)使事情更容易使用,并且有提示“>”更有用。
This code accepts commands and special keys.此代码接受命令和特殊键。 Also, it displays nicely to be used as an interactive shell for your system.此外,它可以很好地用作系统的交互式 shell。
DELETE
key will remove all chars and BACKSPACE
a single character. DELETE
键将删除所有字符并BACKSPACE
单个字符。 ESC
will exit the shell. ESC
将退出外壳。 You can add more keys to include arrows or anything else to perform special functions.您可以添加更多键以包含箭头或其他任何执行特殊功能的键。 This code will print-out any special key pressed which is not included inside the if..elsif
(so you know what you need to add).此代码将打印出任何未包含在if..elsif
特殊按键(因此您知道需要添加什么)。
use warnings;
use strict;
use Term::RawInput;
sub out {
my $out = shift;
print "[ $out ]\n";
}
do {
my ($keystroke,$special) = rawInput("> ");
if($special eq 'ESC') {
print "\n";
exit;
} elsif($special eq 'ENTER') {
out($keystroke);
} elsif($special ne 'DELETE') {
if ($keystroke ne '') {
out($keystroke);
} else {
print "'$special' key is not associated\n";
}
}
} while(1);
You can implement your commands inside "out";您可以在“out”内执行您的命令;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.