繁体   English   中英

QKeyEvent isAutoRepeat无法正常工作吗?

[英]QKeyEvent isAutoRepeat not working?

因此,我有一个应用程序,如果按住某个特定按钮,它将播放音频设备,释放该按钮时,它将停止音频设备。 我使用keyPressEventKeyReleaseEvent来实现这一点,类似于下面的代码:

void MainWindow::keyPressEvent(QKeyEvent *event)
{
    if(event->isAutoRepeat())
    {
        event->ignore();
    }
    else
    {
        if(event->key() == Qt::Key_0)
        {
            qDebug()<<"key_0 pressed"<<endl;
        }
        else
        {
            QWidget::keyPressEvent(event);
        }
    }
}

void MainWindow::keyReleaseEvent(QKeyEvent *event)
{
    if(event->isAutoRepeat())
    {
        event->ignore();
    }
    else
    {
        if(event->key() == Qt::Key_0)
        {
            qDebug()<<"key_0 released"<<endl;
        }
        else
        {
            QWidget::keyReleaseEvent(event);
        }
    }
}

但是显然isAutoRepeat函数不起作用,因为尽管按下后我没有松开0键,但我仍能看到连续key_0 pressedkey_0 released key_0 pressed打印。 我的代码错误还是其他错误?

谢谢。

编辑

我认为这是因为MainWindow失去了键盘焦点。 我如何才能真正找出哪个小部件具有焦点? 当按下Qt::Key_0时,我实际上正在使用一些小部件,但是我想我将所有可能的小部件都设置为Qt::NoFocus ,我想它不起作用。

我正在尝试通过执行以下操作来了解哪个小部件具有焦点:

QWidget * wigdet = QApplication::activeWindow();
qDebug()<<wigdet->accessibleName()<<endl;

但它始终显示一个空字符串。 如何使它打印具有键盘焦点的小部件的名称?

因此,当我也无意中遇到了这个问题(并且grabKeyboard并没有真正帮助)时,我开始研究qtbase。 它通过xcb连接到X11,默认情况下,在重复键的情况下,X11为每个重复键发送一个释放事件,紧随其后的是一个按键事件。 因此,按住某个键将导致XCB_BUTTON_RELEASE / XCB_BUTTON_PRESS-事件蜂鸣序列发送到客户端(使用xev或此页面末尾的源进行尝试)。

然后,qt( qtbase / src / plugins / platforms / xcb / qxcbkeyboard.cpp )尝试从这些事件中找出其是否是自动重复的情况:收到发行版时,它使用先行功能来确定是否先后自动按下(时间戳足够接近),并且如果是,则假定为自动重复。

这并不总是有效,至少在所有平台上也是如此。 对于我的情况(旧的和用完的慢速笔记本电脑(运行ubuntu 16.04的Intel®Celeron(R)CPU N2830 @ 2.16GHz×2)),它有助于在检查之前将睡眠状态设置为(500),从而允许发布后的新闻发布会事件到达...大约在qxcbkeyboard.cpp的1525行:

    // look ahead for auto-repeat
    KeyChecker checker(source->xcb_window(), code, time, state);
    usleep(500); // Added, 100 is to small, 200 is ok (for me)
    xcb_generic_event_t *event = connection()->checkEvent(checker);
    if (event) {
    ...

归档为QTBUG-57335

Nb:X的行为可以通过使用来更改

Display *dpy=...;
Bool result;
XkbSetDetectableAutoRepeat (dpy, true, &result);

然后,在按住键的情况下,它不会发送此释放按顺序,但是使用它会需要对autorepeat-detection-logic进行更多更改。

无论如何解决了。

问题是我有一个小部件,它是QGLWidget的子类,用于显示Kinect的一些增强现实图像。 每当按下键盘按钮时,此小部件都会接管键盘焦点。

为了解决这个问题,我需要从MainWindow类( MainWindowQMainWindow的子类)中调用grabKeyboard函数,因此this->grabKeyboard()是按下key_0按钮时需要添加的行,这样MainWindow不会丢失键盘焦点,然后释放键时,我需要添加此行- this->releaseKeyboard()以恢复正常行为,也就是说,其他小部件可以具有键盘焦点。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM