【问题标题】:How to release the focus of QPushButton which is the default button of the QDialog?QDialog的默认按钮QPushButton如何释放焦点?
【发布时间】:2019-07-19 10:15:42
【问题描述】:

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

【问题讨论】:

    标签: c++ qt


    【解决方案1】:

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

    void setAutoDefault(bool)
    

    见:Qt-Documentation

    如果您的对话框中有更多按钮,您还必须将它们的 autoDefault 值设置为 false。否则这些按钮将获得焦点并在按下 enter 时执行。

    【讨论】:

      【解决方案2】:

      这不(直接)依赖于焦点:当小部件不处理事件时,它会被转发到小部件的父级。 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();
      }
      

      【讨论】:

      • 如果我使用这种方法,我将不得不为 QDialog 中的每个小部件创建自己的类,除了 QPushButton。因为我希望所有其他小部件都忽略 Enter 按键。我所做的是,我使用 QDialog 上的 keyPressEvent 来忽略 Enter 按键。它忽略了 QDialog 内每个小部件上的 Enter 按键,包括 QPushButton。但是由于我已经为 QPushButtons clicked 信号编写了插槽,因此在 QPushButton 上按下 Enter 键调用了该插槽。这正是我想要的。谢谢你的回复。
      • 听起来您不想要默认按钮行为。顺便说一句:您也可以使用事件过滤器而不是子类化所有内容:doc.qt.io/qt-5/qobject.html#installEventFilter
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-02-05
      • 2022-11-16
      • 1970-01-01
      • 2021-10-06
      • 1970-01-01
      • 2019-12-06
      • 1970-01-01
      相关资源
      最近更新 更多