11

QLineEdit当用户完成编辑时发出一个信号QLineEdit::editingFinished,例如按下回车键。但是,如果设置了验证器或输入掩码,则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
        });
    }
};
4

1 回答 1

10

我不认为你真的需要子类化QLineEdit

在没有输入时更改值的干净方法是覆盖并提供. 从文档QLineEditAcceptableQValidatorfixup()

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()因为即使QLineEditwere 的内容不是Acceptable,我们的fixup()实现也总是将内容固定为 be Acceptable

于 2016-09-18T14:49:11.797 回答