【问题标题】:How to set focus for button in KeyPressEvent for key_up, key_down. QT如何在 KeyPressEvent 中为 key_up、key_down 设置按钮焦点。 QT
【发布时间】:2022-02-18 02:09:41
【问题描述】:

我有一个带有按钮的表单,名为 "Up""Down" 等。

我需要处理键盘按钮(arrow_uparrow_down 等)。同时我想为相关按钮设置焦点。

例如:如果我按下键盘上的arrow_down 按钮,那么"Down" 按钮将成为我表单上的焦点。

我的变种如何做到这一点:

bool ClientWindow::eventFilter(QObject *obj, QEvent *e)
{
    if (event->type() == QEvent::KeyPress) {
        QKeyEvent *event= dynamic_cast<QKeyEvent*>(e);
        switch(event->key()) {
            case Qt::Key_Up: ui->up->setFocus(); ;break;
            case Qt::Key_Down: ui->down->setFocus(); break;
            case Qt::Key_Left: ui->left->setFocus(); break;
            case Qt::Key_Right: ui->right->setFocus(); break;
        }
    }
    return QObject::eventFilter(obj, event);
}

但是,焦点没有设置,并且

1) 如果我从 eventFilter 返回 true,则不会设置焦点。

2) 如果我返回 QObject::eventFilter(obj, event) 那么焦点将转移到下一个对象。

如何为相关按钮设置焦点?

【问题讨论】:

  • 欢迎来到 SO!我想我明白你在问什么,但请提供一个更完整的例子。什么是客户端窗口? (QObject)上的eventFilter 设置是什么......或者您是否在其自身上设置了一个过滤器(这不是这样做的方法)? ClientWindow 或过滤的对象或 UI 中可能窃取按键的其他任何位置(小部件/布局)是什么?如您所见,许多问题最好用一个完整(但最少)的例子来回答。焦点处理充其量可能有点棘手。

标签: c++ qt button focus


【解决方案1】:

由于您正在尝试更改 Qt 的标准功能(箭头键移动焦点,就像 TAB 键一样),您可能想尝试一个极端的解决方案。

关键是:您的箭头键按下事件是否被过滤了?我的猜测是否定的。 above(或 before)小部件正在使用它们并保持标准行为不变(焦点照常根据它们的选项卡索引从按钮移动到按钮)。 p>

我会尝试在小部件构造函数中将您的过滤器安装到QApplication 对象上:

qApp->installEventFilter(this);

过滤器应如下所示:

bool Widget::eventFilter(QObject *obj, QEvent *e)
{
    if (e->type() == QEvent::KeyPress)
    {
        if(qApp->activeWindow() == this)
        {
            QKeyEvent *event= dynamic_cast<QKeyEvent*>(e);

            switch(event->key()) {
            case Qt::Key_Up: ui->up->setFocus(); break;
            case Qt::Key_Down: ui->down->setFocus(); break;
            case Qt::Key_Left: ui->left->setFocus(); break;
            case Qt::Key_Right: ui->right->setFocus(); break;

            default:
                return qApp->eventFilter(obj, e);

            }
            return true;
        }
    }
    return qApp->eventFilter(obj, e);
}

请注意这一行:

if(qApp->activeWindow() == this)

这应该防止应用过滤器中的规则每当箭头键被按下时(即当小部件不是最上面的小部件时)。如果您的应用程序没有除此之外的其他小部件,您可以忽略它。

最后的建议:尽量不要改变标准的 UI 行为。用户确实希望事情能像往常一样工作,而对于开发人员来说看起来绝对的解决方案,有时(通常)根本不会带来任何改进,只会让用户感到困惑。

【讨论】:

  • 对我来说似乎有点矫枉过正。每个应用程序事件都将通过此过滤器运行。检查关键事件是否在我提出的链上某处被捕获可能很有用。在小部件中实现密钥处理的“正确”方法是重新实现QWidget::key*Event() 方法。或QWidget::event() 的更高级别。恕我直言,使用事件过滤器来监视事件本身并没有真正意义。这就是我要求OP澄清的原因。在setFocus() 调用之后,似乎更有可能有其他东西在窃取焦点,尤其是因为事件从来都不是accepted()
猜你喜欢
  • 2021-05-12
  • 1970-01-01
  • 2014-09-26
  • 2015-03-19
  • 2010-10-06
  • 1970-01-01
  • 2021-12-03
  • 1970-01-01
相关资源
最近更新 更多