Что означает сигнал, когда виджет теряет фокус?

В диалоговом окне при нажатии клавиши tab фокус переключается на другой виджет. Есть ли в Qt какой-либо сигнал, когда виджет теряет фокус? Могу ли я использовать его для проверки правильности ввода или нет? Если нет, могу ли я вернуть фокус и попросить пользователя повторно ввести данные?


person user1899020    schedule 23.07.2013    source источник
comment
Если вас интересует QLineEdit потеря фокуса, сигнал QLineEdit::editingFinished() фиксирует это событие.   -  person waldyrious    schedule 09.06.2016


Ответы (2)


Сигнала нет, но если вы хотите знать, когда ваш виджет потерял фокус, переопределите и переопределите 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;
}

Это не позволит пользователю закрыть диалоговое окно с помощью кнопки OK или любой другой кнопки с ролью Accepted, пока содержимое диалогового окна не будет успешно проверено. В этом примере я предполагаю, что диалог имеет QLineEdit с именем lineEdit, а функция validate проследит, чтобы его содержимое не было пустым. Если это так, он установит фокус на QLineEdit и снова отобразит диалоговое окно.

person Daniel Hedberg    schedule 23.07.2013
comment
На самом деле есть сигнал - QApplication::focusChanged. - person sashoalm; 27.03.2014
comment
содержательный комментарий sashoalm должен быть принятым ответом. Конечно, это так не работает. Попробуйте проголосовать за этот похожий ответ на этот повторяющийся вопрос. </sigh> - person Cecil Curry; 15.09.2017

Также возможно (и проще) создать сигнал самому

В .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);
};

И чтобы его подключить:

connect(new FocusWatcher(myWidget), &FocusWatcher::focusChanged, this, &View::doSomething);
person Emmanuel Lepage Vallee    schedule 12.12.2015