I have a QDialog which has a QPushButton and a QLineEdit. QPushButton is set as the default button. When I run the dialog and click Enter key, QPushButton is clicked and corresponding slot is invoked, which is the expected behavior. But when I click on the QLineEdit using mouse and then click Enter key again, also invoke the QPushButton's clicked slot. How to prevent this? I want to click Enter button on other widgets to do nothing. When I use the Tab key to navigate through widgets, QPushButton's is always bold (highlighted) which I guess the reason why it is invoked every time Enter key is pressed.
2 Answers
1
votes
You have to set the AutoDefault value of the Button to false.
void setAutoDefault(bool)
see: Qt-Documentation
If there are more Buttons in your dialog you also have to set their autoDefault value to false. Otherwise these buttons will get focus and be executed on enter pressed.
1
votes
This doesn't (directly) depend on focus: when a widget doesn't handle an event, it is forwarded to the widget's parent. QLineEdit doesn't handle enter, so it sends it to the QDialog, which activates the default button on enter. The default button is displayed in a special way, e.g. a bold border on your style .
You could write your own QLineEdit subclass that prevents the Enter-event from propagating:
#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();
}