2016-09-17 80 views
2

QLineEdit有一个信号QLineEdit::editingFinished,当用户完成编辑时(例如按下回车键),该信号发出。但是,如果设置了验证器或输入掩码,则只有在输入有效时才会发出editingFinished带QValidator的QLineEdit:无论输入有效性如何,完成编辑完成?

但是,无论输入的有效性如何,我如何才能完成编辑?我是否必须手动检查输入,返回,小部件失去焦点等?

原因是:我想创建一个自定义小部件,用于使用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 
     }); 
    } 
}; 

回答

5

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

改变QLineEdit值时,它不具有Acceptable输入的干净方式,是重写QValidatorfixup()提供实现。来自docs

fixup()被提供用于可以修复一些用户错误的验证器。 默认实现不做任何事情。例如,QLineEdit,如果用户按下Enter(或Return)并且内容 当前不有效,则将 呼叫fixup()。这允许fixup()函数有机会 执行一些魔术来制作Invalid字符串Acceptable

由于您使用QDoubleValidator,你也可以继承它并为fixup()提供的实现,因为它没有一个,见here

类应该是这个样子:

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