QLineEdit with QValidator:不管输入的有效性如何,对编辑完成做出反应

QLineEdit with QValidator: React to editing finished regardless of input validity?

本文关键字:编辑 QValidator with 不管 输入 有效性 QLineEdit      更新时间:2023-10-16

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将会如果用户按Enter(或Return)键,则调用fixup()目前无效。这给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