QLineEdit
имеет сигнал QLineEdit::editingFinished
который выдается, когда пользователь закончил редактирование, например, нажав Enter. Однако, если был установлен валидатор или маска ввода, то editingFinished
испускается, только если ввод действителен.
Но как я могу реагировать на то, что пользователь заканчивает редактирование, независимо от достоверности ввода? Нужно ли вручную проверять ввод, возврат, потерю фокуса виджета и т. Д.?
Причина этого: я хотел создать собственный виджет для редактирования чисел с помощью QDoubleValidator
, Когда пользователь заканчивает редактирование и ввод неверен (неправильный диапазон, пустой текст, …), я хочу сбросить его до некоторого действительного значения по умолчанию. Что-то вроде этого:
class NumberEdit: public QLineEdit
{
public:
NumberEdit(double min, double max)
{
setValidator(new QDoubleValidator(min, max, 10));
setText(QString::number(min));
connect(this, /* this is the problem */, [this, min]() {
if(!hasAcceptableInput())
setText(QString::number(min)); // Reset to valid number
});
}
};
Я не думаю, что вам действительно нужно подкласс QLineEdit
,
чистый способ изменить QLineEdit
значение, когда оно не имеет Acceptable
ввод, переопределить QValidator
и обеспечить реализацию для fixup()
. От документы:
fixup()
предоставляется для валидаторов, которые могут исправлять некоторые пользовательские ошибки.
Реализация по умолчанию ничего не делает.QLineEdit
, например, будет
вызовfixup()
если пользователь нажимает Enter (или Return) и содержимое
в настоящее время не действует. Это позволяетfixup()
использовать возможность
выполнения некоторой магии, чтобы сделатьInvalid
строкаAcceptable
,
Так как вы используете QDoubleValidator
, вы можете создать его подкласс и обеспечить реализацию для fixup()
, так как его нет, посмотри Вот.
Класс должен выглядеть примерно так:
class MyDoubleValidator : public QDoubleValidator{
public:
explicit MyDoubleValidator(QObject* parent= nullptr)
:QDoubleValidator(parent){}
MyDoubleValidator(double bottom, double top, int decimals, QObject* parent=nullptr)
:QDoubleValidator(bottom, top, decimals, parent){}
virtual void fixup(QString& input)const override{
input= QString::number(bottom(), 'f', decimals());
}
};
Таким образом, вы можете просто использовать свой валидатор с любым QLineEdit
как это:
lineEdit->setValidator(new MyDoubleValidator(100, 200, 2, lineEdit));
Обратите внимание, что таким образом lineEdit
будет излучать editingFinished()
после каждого редактирования. Потому что даже если содержимое QLineEdit
не были Acceptable
наш fixup()
реализация всегда будет фиксировать содержание, которое будет Acceptable
,
Других решений пока нет …