【问题标题】:Check keypress in C++ on Linux在 Linux 上检查 C++ 中的按键
【发布时间】:2013-08-19 08:06:49
【问题描述】:

是否有一种简单的方法可以检查是否按下了某个键,以便我可以在线程中循环遍历该键?宁愿不使用图书馆,也绝对不使用 ncurses。我在互联网上没有找到任何有效的方法。

【问题讨论】:

标签: c++ linux keypress


【解决方案1】:

我找到了一个更简单的方法:

#include <X11/Xlib.h>
#include <iostream>
#include "X11/keysym.h"

/**
 *
 * @param ks  like XK_Shift_L, see /usr/include/X11/keysymdef.h
 * @return
 */
bool key_is_pressed(KeySym ks) {
    Display *dpy = XOpenDisplay(":0");
    char keys_return[32];
    XQueryKeymap(dpy, keys_return);
    KeyCode kc2 = XKeysymToKeycode(dpy, ks);
    bool isPressed = !!(keys_return[kc2 >> 3] & (1 << (kc2 & 7)));
    XCloseDisplay(dpy);
    return isPressed;
}

bool ctrl_is_pressed() {
    return key_is_pressed(XK_Control_L) || key_is_pressed(XK_Control_R);
}

int main(int argc, char **argv) {
    std::cout << ctrl_is_pressed() << std::endl;
    return (0);
};

【讨论】:

  • 很好,但我认为这仅在您处于 X 环境中时才有效(换句话说,不能在纯 tty 或 Wayland 下工作)?
  • 这是什么鬼:!!(keys_return[kc2 &gt;&gt; 3] &amp; (1 &lt;&lt; (kc2 &amp; 7)))?好的,这是一些操作,但是这些神奇的数字是从哪里来的?
  • 哦,我明白了。有一个简单的解释:
  • keys_return 是一个32*8 位数组,其中每个编号为kc2 的位是对应键的状态,键码为kc2。我们的目标是将kc2 转换为“二维数组”keys_return 中的某种坐标。为此,我们首先需要通过除以kc2 / 8 来获得正确的行(记住每个“行”是8 位。kc2 &gt;&gt; 3kc2 / 8 相同。然后我们得到“列”kc2 % 8,即和kc2 &amp; 7是一样的。不过,既然有点,就需要换1才能得到。
  • 所以,等价于keys_return[kc2 / 8] &amp; (1 &lt;&lt; (kc2 % 8)。几乎就像arr[n/8][n%8]
【解决方案2】:

试试这个:-

#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#include <termios.h>

int main()
{
    struct termios oldSettings, newSettings;

    tcgetattr( fileno( stdin ), &oldSettings );
    newSettings = oldSettings;
    newSettings.c_lflag &= (~ICANON & ~ECHO);
    tcsetattr( fileno( stdin ), TCSANOW, &newSettings );    

    while ( 1 )
    {
        fd_set set;
        struct timeval tv;

        tv.tv_sec = 10;
        tv.tv_usec = 0;

        FD_ZERO( &set );
        FD_SET( fileno( stdin ), &set );

        int res = select( fileno( stdin )+1, &set, NULL, NULL, &tv );

        if( res > 0 )
        {
            char c;
            printf( "Input available\n" );
            read( fileno( stdin ), &c, 1 );
        }
        else if( res < 0 )
        {
            perror( "select error" );
            break;
        }
        else
        {
            printf( "Select timeout\n" );
        }
    }

    tcsetattr( fileno( stdin ), TCSANOW, &oldSettings );
    return 0;
}

来自here

【讨论】:

  • 在 windows!os/2!dos 域中俗称 kbhit。请记住,您必须获得密钥,否则这将继续报告有可用的按键。当这表明密钥准备就绪时调用 getch()。
猜你喜欢
  • 1970-01-01
  • 2016-05-08
  • 1970-01-01
  • 2018-08-31
  • 1970-01-01
  • 1970-01-01
  • 2020-03-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多