Qt keyPressEvent、“Hold”和keyReleaseEvent处理按钮/鼠标点击

Posted

技术标签:

【中文标题】Qt keyPressEvent、“Hold”和keyReleaseEvent处理按钮/鼠标点击【英文标题】:Qt keyPressEvent, "Hold", and keyReleaseEvent Handling with Buttons/Mouse Clicks 【发布时间】:2014-09-14 21:59:27 【问题描述】:

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

应用程序使用 QPushButton 并启用 autoRepeat 和 100 毫秒 autoRepeatDelayautoRepeatInterval。如果我鼠标单击按钮,我会收到交替的“按下”和“释放”事件。我本来希望看到 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 中做的事情可能吗?

【问题讨论】:

"如果启用了自动重复,那么当按钮按下时,pressed()、release() 和 clicked() 信号会定期发出。一开始我并没有完全理解这一点——看起来这是重复事件的根源。我必须生成自己的解决方案。 您期望的行为似乎与 Windows API 相当......但 X11 Gui 的工作方式不同......不知道关于 Wayland。我的猜测是 qt 模拟了统一的行为 【参考方案1】:

这是我的解决方案:首先我禁用了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”事件并清除标志。

它现在正在工作。

【讨论】:

【参考方案2】:

这是由 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();

【讨论】:

以上是关于Qt keyPressEvent、“Hold”和keyReleaseEvent处理按钮/鼠标点击的主要内容,如果未能解决你的问题,请参考以下文章

Qt keyPressEvent

qt keypressevent()中的多个键

PyQt5 keyPressEvent 不适用于终止 App Qt Designer

qt keyPressEvent函数方向键没有响应键盘事件的解决方法

qt keyPressEvent函数方向键没有响应键盘事件的解决方法

Qt 中响应回车事件 keyPressEvent