3

我正在编写一个 Qt 程序来模拟一个硬件,我想模拟按钮按下、按住和释放事件。在我的应用程序中,我想处理来自键盘和鼠标点击的输入,以方便用户(即我)。我注意到一些奇怪的行为,我不明白。

该应用程序使用autoRepeat启用的 QPushButton 和 100 msautoRepeatDelayautoRepeatInterval. 如果我用鼠标点击一个按钮,我会收到交替的“按下”和“释放”事件。我本来希望看到 1 到 N-1 个“按下”事件,然后是一个“发布”事件。为什么 Qt 会这样?

我还实现了以下代码来处理来自键盘的按钮按下:

void MyApp::keyPressEvent(QKeyEvent *event)
{
    QString s = QString("My PRESS key is %1. The counter is %2").arg(event->text(), QString::number(keyCounter));
    qDebug() << s;
    keyCounter++;
}

void MyApp::keyReleaseEvent(QKeyEvent *event)
{
    QString s = QString("My RELEASE key is %1. The counter is %2").arg(event->text(), QString::number(keyCounter));
    qDebug() << s;
    keyCounter = 0;
}

bool MyApp::eventFilter(QObject *obj, QEvent *event)
{
    if (event->type() == QEvent::KeyPress)
    {
        this->keyPressEvent(dynamic_cast<QKeyEvent*>(event));
        return true;
    }
    else if (event->type() == QEvent::KeyRelease)
    {
        this->keyReleaseEvent(dynamic_cast<QKeyEvent*>(event));
        return  true;
    }
    else
    {
        return QObject::eventFilter(obj, event);
    }
}

在这里,我看到了两种类型的行为。对于字母数字键,我看到交替的“按下”和“释放”事件。对于箭头键,我只看到“已发布”事件。同样,我本来希望看到 1 到 N-1 个“按下”事件,然后是“释放”事件。为什么箭头键的行为与字母数字键不同?

我想在 Qt 中做的事情可能吗?

4

2 回答 2

3

这是我的解决方案:首先我禁用autoRepeat并停止处理keyPressEvents,因为我发现箭头键没有生成它们。相反,我为我想使用的键盘按钮注册了快捷键:

QShortcut *shortcutUp = new QShortcut(QKeySequence("Up"), this);
QObject::connect(shortcutUp, SIGNAL(activated()), this, SLOT(on_upButton_pressed()));
shortcutUp->setAutoRepeat(false);

然后在on_upButton_pressed()函数中(例如)我设置了一个标志,指示按钮被按下。该标志在on_upButton_released()函数中被清除。每隔 100 毫秒检查一次该标志(使用 QTimer)。如果标志为真,我on_upButton_pressed()再打电话。这表示:

  • 每次鼠标单击或键盘按钮按下都会生成一个“Press”事件
  • "Press" 事件设置一个由 QTimer 检查的标志
  • 如果标志为true,则生成另一个“Press”事件
  • 当鼠标或键盘按钮被释放时,会产生“Release”事件并清除标志。

它现在正在工作。

于 2014-09-17T02:20:41.173 回答
0

这是由 QT 中的某些键生成自动重复事件引起的:

在这里,我看到了两种类型的行为。对于字母数字键,我看到交替的“按下”和“释放”事件。对于箭头键,我只看到“已发布”事件。同样,我本来希望看到 1 到 N-1 个“按下”事件,然后是“释放”事件。为什么箭头键的行为与字母数字键不同?

在 QT5 中,您可以检测对象功能按下的isAutoRepeat()QKeyEvent。如果键被按住然后isAutoRepeat()将返回true。例如:

void MainWindow::keyPressEvent(QKeyEvent *event)
{
    if (event->isAutoRepeat())
    {
        return;
    }

    if (!event->isAutoRepeat())
    {
        qDebug() << "[MainWindow::keyPressEvent()] " << event->key() << "; " << event->isAutoRepeat();
    }
}

void MainWindow::keyReleaseEvent(QKeyEvent *event)
{
    if (event->isAutoRepeat())
    {
        return;
    }
    qDebug() << "[MainWindow::keyReleaseEvent()] " << event->key() << "; " << event->isAutoRepeat();
}
于 2020-06-26T02:47:58.683 回答