如何释放QDialog的默认按钮QPushButton的焦点?

时间:2019-07-19 10:15:42

标签: c++ qt

我有一个QDialog,它具有QPushButton和QLineEdit。 QPushButton设置为默认按钮。当我运行对话框并单击Enter键时,单击QPushButton并调用相应的插槽,这是预期的行为。但是,当我使用鼠标单击QLineEdit并再次单击Enter键时,还要调用QPushButton的单击插槽。如何预防呢?我想单击其他窗口小部件上的Enter按钮而不执行任何操作。当我使用Tab键浏览小部件时,QPushButton始终为粗体(突出显示),我想这是每次按下Enter键时都要调用它的原因。

2 个答案:

答案 0 :(得分:1)

这不(直接)取决于焦点:当小部件不处理事件时,它将转发给小部件的父级。 QLineEdit不处理回车,因此将其发送到QDialog,后者激活回车时的默认按钮。默认按钮以特殊方式显示,例如风格上的粗体边框。

您可以编写自己的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();
}

答案 1 :(得分:0)

您必须将Button的AutoDefault值设置为false。

void setAutoDefault(bool)

请参阅:Qt-Documentation

如果对话框中还有更多按钮,则还必须将其autoDefault值设置为false。否则,这些按钮将获得焦点并在按下Enter键后执行。