Allow entry in QLineEdit only within range of QDoubleValidator

前端 未结 7 740
傲寒
傲寒 2020-12-16 05:52

I have a set of QLineEdits that are supposed to accept double values within a certain range, (e.g., -15 to 15).

I have something along these lines when

7条回答
  •  青春惊慌失措
    2020-12-16 06:42

    I came across this solution when searching for a solution, which supports scientific as well as standard notation. It is inspired by the suggestion by Petri Pyöriä, here is a solution, which uses the signal editingFinished.

    I have overloaded validate to ensure that QValidator::Acceptable is returned even when the value is out of range. This triggers the editingFinished, which I use for truncating the output. In this way, both Scientific and Standard notation can be used exactly as implemented by QDoubleValidator

    #include 
    
    class TruncationValidator : public QDoubleValidator
    {
        Q_OBJECT
    public:
        explicit TruncationValidator(QObject *parent = 0) : QDoubleValidator(parent) {
          connect(this->parent(), SIGNAL(editingFinished()), this, SLOT(truncate()));
        }
        TruncationValidator(double bottom, double top, int decimals, QObject * parent) : QDoubleValidator(bottom, top, decimals, parent) {
          connect(this->parent(), SIGNAL(editingFinished()), this, SLOT(truncate()));
        }
    
        QValidator::State validate(QString &s, int &i) const {
          QValidator::State state = QDoubleValidator::validate(s,i);
    
          if (s.isEmpty()) {
            return state;
          }
    
          bool ok;
          double d = s.toDouble(&ok);
    
          if (ok) {
            // QDoubleValidator returns QValidator::Intermediate if out of bounds
            return QValidator::Acceptable;
          }
          return state;
        }
    
    private slots:
        void truncate() {
          QLineEdit* le = dynamic_cast(parent());
          if (le) {
            QString s = le->text();
            bool ok;
            double d = s.toDouble(&ok);
            if (ok) {
              if (d > this->top() || d < this->bottom()) {
                d = std::min(d, this->top());
                d = std::max(d, this->bottom());
                le->setText(QString::number(d));
              }
            }
          }
        }
    private:
    };
    

提交回复
热议问题