【问题标题】:Ncurses reading numpad keys and escapingNcurses 读取小键盘键和转义
【发布时间】:2013-06-03 05:53:00
【问题描述】:

我正在尝试使用 ESC 来逃避使用 getch() 的程序。我创建了一个小程序来演示我的问题。

#include <ncurses.h>

int main(void) {

    int key = 0;

    initscr();
    noecho();
    keypad(stdscr, TRUE);

    do {

        key = getch();
        clear();
        mvprintw(0, 0, "Key = %d\n", key);
        refresh();

    } while (key != 27); 

    clear();
    refresh();
    endwin();
    return 0;

}

我正在尝试允许用户使用箭头键或键盘(哪个更方便)

问题出在小键盘上(numlock 是否打开)。当我编译并运行程序并尝试在这个简单的测试中使用小键盘键时,它会在我触摸小键盘键时立即退出。如果我删除 while (key != 27) (esc 为 27) 条件,它会读取键并显示它们的数字。为什么小键盘注册为时退出循环

ENTER   343
UP      120
DOWN    114
LEFT    116
RIGHT   118

非常感谢任何帮助!

【问题讨论】:

  • 您的程序将有效地仅显示多字节转义序列的最后一个字节,如果您没有将键盘设置为 true,则会发送该字节。由于此类序列以转义开头,它们将导致您的程序退出。我对值 114、116、118 和 120 感到困惑;它们对应于哪些键盘数字?
  • 尝试在调用 initscr() 之前添加setenv("ESCDELAY","1000");。如果不起作用,请尝试更大的值而不是 1000。
  • 您的 TERM 环境变量设置为什么,您在哪个终端上运行测试?

标签: c linux bash ncurses getch


【解决方案1】:

我在 Dungeon Crawl Stone Soup 的源代码中找到了修复程序。它基本上为这些设置了键码。

{DCSS-dir}/source/libunix.cc (333)

define_key("\033Op", 1000);
define_key("\033Oq", 1001);
define_key("\033Or", 1002);
define_key("\033Os", 1003);
define_key("\033Ot", 1004);
define_key("\033Ou", 1005);
define_key("\033Ov", 1006);
define_key("\033Ow", 1007);
define_key("\033Ox", 1008);
define_key("\033Oy", 1009);

// non-arrow keypad keys (for macros)
define_key("\033OM", 1010); // Enter
define_key("\033OP", 1011); // NumLock
define_key("\033OQ", 1012); // /
define_key("\033OR", 1013); // *
define_key("\033OS", 1014); // -
define_key("\033Oj", 1015); // *
define_key("\033Ok", 1016); // +
define_key("\033Ol", 1017); // +
define_key("\033Om", 1018); // .
define_key("\033On", 1019); // .
define_key("\033Oo", 1020); // -

// variants.  Ugly curses won't allow us to return the same code...
define_key("\033[1~", 1031); // Home
define_key("\033[4~", 1034); // End
define_key("\033[E",  1040); // center arrow

【讨论】:

  • PSA:有趣的是,我是 dcss devteam 的成员,多年后,我在试图弄清楚这些映射来自哪里时遇到了这个答案。不建议盲目使用这个,至少其中一些是错误的。 (特别是,我所知道的是\033OP\033OS 在大多数情况下更常用于 F1-F4,我完全不确定在什么情况下这些用于数字键盘键。)
【解决方案2】:

如果 Num Lock 关闭,XTERM 终端仿真器会为某些数字键盘键发送转义。

您可以打开 Num Lock、使用小键盘以外的其他工具、使用 ESC 以外的其他工具来中断循环,或者尝试找到不这样做的终端仿真器。当 Num Lock 在终端模拟器范围内关闭时,您的程序无法区分 ESC 和某些数字键盘字符。

【讨论】:

  • 是的,这也是我通过实验和阅读得出的结论。 @James C,我认为这里最简单的解决方案是 not 使用 ESC 作为循环的结束条件。将 用于其他内容。请注意,在我的系统上,只有 Home/7 和 End/1 键(数字锁定关闭)产生键码 27。我也同意 rici 的方向键。我的值在 258-261 范围内。 Ncurses 在 pgm 中有用于这些的常量,例如KEY_HOME、KEY_END、KEY_RIGHT 等等。
  • ncurses 应该处理这个问题。在 ncurses 收到一个 ESC 字符后,它会在 ESCDELAY 环境变量(默认为 1000)中等待毫秒数,并且只有在没有多字符序列到达时才会发送 Esc 字符。出于这个原因,您可能会注意到在您的 ncurses 程序响应之前按 Esc 后会出现延迟。您的程序在 xterm 内的我的系统上完美运行。
  • @Craig 你绝对肯定你没有打开 Num Lock 吗?按小键盘字符时会打印什么字符代码?
  • @MaxwellHansen 数字键盘“8”给我 56 关闭数字锁定和 259 关闭数字锁定(259 是 ncurses.h 中定义的 KEY_UP)数字键盘上没有的向上箭头也返回 259跨度>
  • @Craig,数字键盘上的 8 键在我的系统上也可以正常工作。只有 1、3、5、7 和 9 为我发送逃生。这就是为什么我在回答哪些数字键盘键发送 ESC 时含糊其辞。它似乎因用户而异,但我不确定不一致的根源是什么。
猜你喜欢
  • 2012-03-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-03
  • 2014-09-18
  • 1970-01-01
  • 2014-08-19
  • 2012-08-15
  • 2022-01-20
相关资源
最近更新 更多