В диалоговом окне при нажатии клавиши tab фокус переключается на другой виджет. Есть ли в Qt какой-либо сигнал, когда виджет теряет фокус? Могу ли я использовать его для проверки правильности ввода или нет? Если нет, могу ли я вернуть фокус и попросить пользователя повторно ввести данные?
Что означает сигнал, когда виджет теряет фокус?
Ответы (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
и снова отобразит диалоговое окно.
QApplication::focusChanged
.
- person sashoalm; 27.03.2014
</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);
QLineEdit
потеря фокуса, сигналQLineEdit::editingFinished()
фиксирует это событие. - person waldyrious   schedule 09.06.2016