如何释放QPushButton的焦点,这是QDialog的默认按钮

How to release the focus of QPushButton which is the default button of the QDialog?

本文关键字:焦点 QDialog 默认按钮 这是 QPushButton 何释放 释放      更新时间:2023-10-16

我有一个QDialog,它有一个QPushButton和一个QLineEdit。QPush按钮设置为默认按钮。当我运行对话框并单击 Enter 键时,单击 QPushButton 并调用相应的插槽,这是预期的行为。但是当我使用鼠标单击 QLineEdit 然后再次单击 Enter 键时,也会调用 QPushButton 的单击插槽。如何预防这种情况?我想单击其他小部件上的 Enter 按钮什么都不做。当我使用 Tab 键浏览小部件时,QPushButton 的总是粗体(突出显示(,我想这就是每次按下 Enter 键时都会调用它的原因。

您必须将

按钮的自动默认值设置为 false。

void setAutoDefault(bool)

参见:Qt文档

如果对话框中有更多按钮,您还必须将其自动默认值设置为 false。否则,这些按钮将获得焦点并在按下回车键时执行。

这(直接(不依赖于焦点:当小部件不处理事件时,它会转发到小部件的父级。QLineEdit 不处理 enter,因此它会将其发送到 QDialog,QDialog 会在 Enter 时激活默认按钮。默认按钮以特殊方式显示,例如样式上的粗体边框。

您可以编写自己的 QLineEdit 子类来防止 Enter-事件传播:

#include <QtWidgets>
class MyLineEdit : public QLineEdit
{
public:
    MyLineEdit(QWidget *parent = nullptr) : QLineEdit(parent) {}
protected:
    void keyPressEvent(QKeyEvent *event) {
        if (event->key() == Qt::Key_Return) {
            event->accept(); // I have handled the event, don't propagate
        } else {
            QLineEdit::keyPressEvent(event);
        }
    }
};
int main(int argc, char **argv)
{
    QApplication app(argc, argv);
    QDialog d;
    QLineEdit *l = new MyLineEdit(&d);
    QPushButton *b = new QPushButton("Ok", &d);
    b->setDefault(true);
    QHBoxLayout *h = new QHBoxLayout(&d);
    h->addWidget(l, 1);
    h->addWidget(b);
    QObject::connect(b, &QPushButton::clicked, [&]{QMessageBox::information(&d, "OK", "OK");});
    d.show();
    return app.exec();
}