测试是否在 Linux 上不阻塞地按下键

Test whether key is pressed without blocking on Linux

我正在搜索如何测试是否按下了某个键。测试不应阻止程序。如果它不是太重的话,我可以使用一个小库,但不幸的是 ncurses 太依赖了。

我不知道你在找什么。

  • 我最近在此处从 "raw" 输入设备节点进行了概念验证阅读:。该示例使用鼠标,但 Linux 内核统一了输入设备,因此键盘大致相同。

    您在这里只需要 open/read 设备文件的 UNIX 权限(如果您的部署方式更方便,您可以创建它们 out-of-/etc-tree)。

    示例显示事件的完全异步处理

  • 我已经使用绑定到 XTest (libxtst)(实际上是为了发送击键);我想这可能包含您需要的功能

  • 然后是 XInput,它(据我所知)构成了 XOrg 方法来抽象我在第一个选项中描述的 "raw" 输入设备流

我找到了解决方案:

int khbit() const
{
    struct timeval tv;
    fd_set fds;
    tv.tv_sec = 0;
    tv.tv_usec = 0;
    FD_ZERO(&fds);
    FD_SET(STDIN_FILENO, &fds);
    select(STDIN_FILENO+1, &fds, NULL, NULL, &tv);
    return FD_ISSET(STDIN_FILENO, &fds);
}

void nonblock(int state) const
{
    struct termios ttystate;
    tcgetattr(STDIN_FILENO, &ttystate);

    if ( state == 1)
    {
        ttystate.c_lflag &= (~ICANON & ~ECHO); //Not display character
        ttystate.c_cc[VMIN] = 1;
    }
    else if (state == 0)
    {
        ttystate.c_lflag |= ICANON;
    }
    tcsetattr(STDIN_FILENO, TCSANOW, &ttystate);
}

bool keyState(int key) const //Use ASCII table
{
    bool pressed;
    int i = khbit(); //Alow to read from terminal
    if (i != 0)
    {
        char c = fgetc(stdin);
        if (c == (char) key)
        {
            pressed = true;
        }
        else
        {
            pressed = false;
        }
    }

    return pressed;
}

int main()
{
    nonblock(1);
    int i = 0;
    while (!i)
    {
        if (cmd.keyState(32)) //32 in ASCII table correspond to Space Bar
        {
            i = 1;
        }
    }
    nonblock(0);

    return 0;
}

效果很好。谢谢你帮助我。我希望它会对某人有所帮助:)