我正在寻找如何测试按键是否被按下,测试不应该阻塞程序。如果没有太多依赖,我可以使用一个小型库,但不幸的是ncurses太重了。
我正在寻找如何测试按键是否被按下,测试不应该阻塞程序。如果没有太多依赖,我可以使用一个小型库,但不幸的是ncurses太重了。
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;
}
它运行良好。感谢你的帮助。我希望它能帮助到其他人 :)
usleep()
(这不是我的情况,所以我没有必要),并且在使用后不要忘记恢复回显状态:在nonblock()
中使用ttystate.c_lflag |= ICANON | ECHO;
。 - Shlublu我不知道你具体在寻找什么。
我最近在这里从“原始”输入设备节点进行了概念验证阅读:boost::asio read from /dev/input/event0。示例是使用鼠标,但Linux内核统一了输入设备,因此键盘也差不多。
你所需要的只是UNIX权限来打开/读取设备文件(如果这对你的部署方式更方便,你可以将它们创建在/etc-tree之外)。
该示例显示了完整的事件异步处理
我已经使用XTest绑定(libxtst
)(实际上是发送按键),我想这可能包含你需要的功能
然后还有XInput,它(据我所知)构成了XOrg抽象“原始”输入设备流的方式,我在第一个选项中描述了它们