如何使用 QEvents 在 Qt 中模拟 QPushButton 单击

Posted

技术标签:

【中文标题】如何使用 QEvents 在 Qt 中模拟 QPushButton 单击【英文标题】:How to emulate a QPushButton click in Qt with QEvents 【发布时间】:2012-01-02 09:34:16 【问题描述】:

我在嵌入式系统上有一个自定义输入设备,并且必须将输入转换为 Qt 中的适当事件。在我当前的视图中,我有一个 QListView 和一些 QPushButtons。我在我的小部件中使用以下代码。

QKeyEvent * e = NULL;
if (cmd.up.value)
    e = new QKeyEvent(QEvent::KeyPress, Qt::Key_Up, 0, 0);
else if (cmd.down.value)
    e = new QKeyEvent(QEvent::KeyPress, Qt::Key_Down, 0, 0);
else if (cmd.left.value)
    e = new QKeyEvent(QEvent::KeyPress, Qt::Key_Left, 0, 0);
else if (cmd.right.value)
    e = new QKeyEvent(QEvent::KeyPress, Qt::Key_Right, 0, 0);
else if (cmd.ok.value)
    e = new QKeyEvent(QEvent::KeyPress, Qt::Key_Space, 0, 0);

if (e)
    QApplication::postEvent(this->focusWidget(), e);

我可以在列表和按钮之间向上/向下/向右/向左移动,但无法单击按钮。我也尝试过使用 Qt::Key_Enter 和 Qt::Key_Return,但都不起作用。

如果在我的电脑上运行该应用程序,在我的键盘上按空格键或鼠标左键会单击一次按钮。这表明在某处,事件被更改为按钮喜欢的东西,而不是直接获取 Qt::Key_Space,对吧?

有人知道如何很好地解决这个问题吗?我可以检查哪个(如果有)按钮有焦点并手动单击它,但这不是很优雅的编码...

【问题讨论】:

您是否尝试过使用 QMouseEvent 向按钮发送鼠标点击? 我的回答有问题吗?请告诉我是否有,我可能可以提供更多帮助。 【参考方案1】:

[QT_FOLDER]/src/gui/widgets/qpushbutton.cpp:第 459 行

如果 defaultButton 设置为 true,QPushButton 接受 Key_Enter 和 Key_Return。我不知道空格按钮在哪里更改为不同的东西,但这是我的修复:

创建一个 MyPushButton 类并重新实现 keyPressEvent。然后只需调用 click

来处理 Enter 和 Return

应该很简单。

编辑:

或者,如果您喜欢,可以为您的设备创建自己的自定义事件,并完全按照您的意愿在派生类中处理这些事件。

【讨论】:

感谢您的回复。我已经尝试了这两种方法,并最终介于两者之间。需要它输入的小部件实现了一个事件处理程序,该处理程序将自定义输入转换为该小部件中子项所需的 QEvent。我使用的按钮设置为 autoDefault,所以从源代码看来应该也可以工作。无论如何-结合您的建议-自定义输入处理程序在活动按钮上调用click()。谢谢。【参考方案2】:

这个问题的解决方案其实很简单。 QPushButton 不是在 KeyPress 上单击,而是在 KeyRelease 上单击。下面是新代码。

if (cmd.up.value)

    QApplication::postEvent(this->focusWidget, 
                            new QKeyEvent(QEvent::KeyPress, Qt::Key_Up, 0, 0));

else if (cmd.down.value)

    QApplication::postEvent(this->focusWidget, 
                            new QKeyEvent(QEvent::KeyPress, Qt::Key_Down, 0, 0));

else if (cmd.left.value)

    QApplication::postEvent(this->focusWidget, 
                            new QKeyEvent(QEvent::KeyPress, Qt::Key_Left, 0, 0));

else if (cmd.right.value)

    QApplication::postEvent(this->focusWidget, 
                            new QKeyEvent(QEvent::KeyPress, Qt::Key_Right, 0, 0));

else if (cmd.ok.value) 

    QApplication::postEvent(this->focusWidget, 
                            new QKeyEvent(QEvent::KeyPress, Qt::Key_Space, 0, 0));
    QApplication::postEvent(this->focusWidget, 
                            new QKeyEvent(QEvent::KeyRelease, Qt::Key_Space, 0, 0));

【讨论】:

以上是关于如何使用 QEvents 在 Qt 中模拟 QPushButton 单击的主要内容,如果未能解决你的问题,请参考以下文章

Qt之QEvent(所有事件的翻译)

Qt 之 QEvent

Qt 之 QEvent

如何在 Qt 中模拟消息总线?

如何使用Qt进行post get模拟登录

如何在 pytest-qt 中处理模态对话框而不模拟对话框