小部件失去焦点时的信号是什么?

use*_*020 29 qt qt4 qdialog qt5

在对话框中,tab按下该键时,焦点将更改为另一个小部件.在Qt中,是否有任何关于小部件失去焦点的信号?我可以用它来检查输入是否有效吗?如果没有,我可以设置焦点并要求用户重新输入吗?

Dan*_*erg 19

没有信号,但如果您想知道您的小部件何时失去焦点,请void QWidget::focusOutEvent(QFocusEvent* event)在窗口小部件中覆盖和重新实现.只要您的小部件失去焦点,就会调用它.要将焦点放在窗口小部件上,请使用QWidget::setFocus(Qt::FocusReason).

为了验证输入一个QLineEdit或者QComboBox你也可以继承QValidator,并实现自己的验证,或者使用现有的一个子类,QIntValidator,QDoubleValidator,或QRegExpValidator.分别用QLineEdit::setValidator(const QValidator*)和设置验证器QComboBox::setValidator(const QValidator*).

如果要验证模式对话框的内容,一种方法是QDialog::exec()使用如下的实现覆盖:

int MyDialog::exec() {
  while (true) {
    if (QDialog::exec() == QDialog::Rejected) {
      return QDialog::Rejected;
    }
    if (validate()) {
      return QDialog::Accepted;
    }
  }
}

bool MyDialog::validate() {
  if (lineEdit->text().isEmpty()) {
    QMessageBox::critical(this, "Invalid value", "The specified value is not valid");
    lineEdit->setFocus();
    lineEdit->selectAll();
    return false;
  }
  return true;
}
Run Code Online (Sandbox Code Playgroud)

除非成功验证对话框的内容,否则不允许用户使用"确定"按钮或具有"已接受"角色的任何其他按钮关闭对话框.在这个例子中,我假设对话框有一个QLineEdit命名lineEdit,该validate函数将确保其内容不为空.如果是,则将焦点设置为QLineEdit并再次显示对话框.

  • 有实际上是一个信号 - [`的QApplication :: focusChanged`](http://qt-project.org/doc/qt-5.0/qtwidgets/qapplication.html#focusChanged). (14认同)

Emm*_*lee 9

您自己也可以(并且更容易)创建信号

在.cpp中(别忘了包含moc)

class FocusWatcher : public QObject
{
   Q_OBJECT
public:
   explicit FocusWatcher(QObject* parent = nullptr) : QObject(parent)
   {
      if (parent)
         parent->installEventFilter(this);
   }
   virtual bool eventFilter(QObject *obj, QEvent *event) override
   {
      Q_UNUSED(obj)
      if (event->type() == QEvent::FocusIn)
         emit focusChanged(true);
      else if (event->type() == QEvent::FocusOut)
         emit focusChanged(false);

      return false;
   }

Q_SIGNALS:
   void focusChanged(bool in);
};
Run Code Online (Sandbox Code Playgroud)

并连接它:

connect(new FocusWatcher(myWidget), &FocusWatcher::focusChanged, this, &View::doSomething);
Run Code Online (Sandbox Code Playgroud)