QDoubleSpinBox with leading zeros (always 4 digits)
Asked Answered
A

2

6

I have a QDoubleSpinBox in range 0-7000, but want the value always displayed as 4 digits (0-> 0000, 1 -> 0001 , 30 -> 0030, 3333 -> 3333).

I understand I can add a prefix, but a prefix is always added. What are my options?

Anzovin answered 23/10, 2014 at 21:5 Comment(0)
A
13

If you use integers, then QSpinBox will be enough.

You can simply inherit from QSpinBox and re-implement the textFromValue function:

class MySpinBox: public QSpinBox 
{
    Q_OBJECT

public:
    MySpinBox( QWidget * parent = 0) :
        QSpinBox(parent)
    {
    }

    virtual QString textFromValue ( int value ) const
    {
        /* 4 - number of digits, 10 - base of number, '0' - pad character*/
        return QString("%1").arg(value, 4 , 10, QChar('0'));
    }
};

Filling QString this way does the trick.

Alvita answered 23/10, 2014 at 22:30 Comment(0)
D
1

Since prefix is not an option solution if you consider negative values, in my opinion the best and most elegant solution is defining your own custom spin box by deriving QAbstractSpinBox. Here is a small example:

Note that it is far from perfection and it serves just as an example on what could be done:

q4digitspinbox.h:

#ifndef Q4DIGITSPINBOX_H
#define Q4DIGITSPINBOX_H

#include <QAbstractSpinBox>
#include <QLineEdit>

class Q4DigitSpinBox : public QAbstractSpinBox
{
    Q_OBJECT

public:
    explicit Q4DigitSpinBox(QWidget *parent = 0);

    StepEnabled stepEnabled() const;
    double maximum() const;
    double minimum() const;
    void setMaximum(double max);
    void setMinimum(double min);
    void setRange(double minimum, double maximum);
    double value() const;

public slots:
    virtual void stepBy(int steps);
    void setValue(double val);

signals:
    void valueChanged(double i);
    void valueChanged(const QString & text);

private:
    double m_value;
    double m_minimum;
    double m_maximum;
    QLineEdit m_lineEdit;
};

#endif // Q4DIGITSPINBOX_H

q4digitspinbox.h:

#include "q4digitspinbox.h"

Q4DigitSpinBox::Q4DigitSpinBox(QWidget *parent) :
    QAbstractSpinBox(parent),
    m_value(0),
    m_minimum(-99),
    m_maximum(99)
{
    setLineEdit(&m_lineEdit);
    setValue(0.0);
}

QAbstractSpinBox::StepEnabled Q4DigitSpinBox::stepEnabled() const
{
    return StepUpEnabled | StepDownEnabled;
}

double Q4DigitSpinBox::maximum() const
{
    return m_maximum;
}

double Q4DigitSpinBox::minimum() const
{
    return m_minimum;
}

void Q4DigitSpinBox::setMaximum(double max)
{
    m_maximum = max;
}

void Q4DigitSpinBox::setMinimum(double min)
{
    m_minimum = min;
}

void Q4DigitSpinBox::setRange(double minimum, double maximum)
{
    m_minimum = minimum;
    m_maximum = maximum;
}

double Q4DigitSpinBox::value() const
{
    return m_value;
}

void Q4DigitSpinBox::stepBy(int steps)
{
    m_value += (double)steps / 10;

    if (fabs(m_value - 0) < 0.00001)
    {
        m_value = 0;
    }

    if(m_value < m_minimum || m_value > m_maximum)
    {
        return;
    }

    int prefixNumberOfDigits = 4;
    QString valueAsString = QString("%1").arg((int)m_value);
    int numberOfDigits = valueAsString.length();

    QString prefix;
    prefixNumberOfDigits -= numberOfDigits;

    if(prefixNumberOfDigits > 0)
    {
        while(prefixNumberOfDigits--)
        {
            prefix += "0";
        }
    }

    QString value;

    if(m_value < 0)
    {
        value = QString("-%1%2").arg(prefix).arg(-m_value);
    }
    else
    {
        value = QString("%1%2").arg(prefix).arg(m_value);
    }

    m_lineEdit.setText(value);

    emit valueChanged(m_value);
    emit valueChanged(value);
}

void Q4DigitSpinBox::setValue(double val)
{
    if(val < m_minimum || val > m_maximum)
    {
        return;
    }

    int prefixNumberOfDigits = 4;
    QString valueAsString = QString("%1").arg((int)val);
    int numberOfDigits = valueAsString.length();

    QString prefix;
    prefixNumberOfDigits -= numberOfDigits;

    if(prefixNumberOfDigits > 0)
    {
        while(prefixNumberOfDigits--)
        {
            prefix += "0";
        }
    }

    QString value;

    if(val < 0)
    {
        value = QString("-%1%2").arg(prefix).arg(-val);
    }
    else
    {
        value = QString("%1%2").arg(prefix).arg(val);
    }

    m_lineEdit.setText(value);

    emit valueChanged(val);
    emit valueChanged(value);
}

I didn't provide any commentary since I considered it pretty straight forward, but if needed I can add a few more explanations.

I hope this helps.

Doubleminded answered 24/10, 2014 at 0:15 Comment(1)
own class is the solution, but overriding textFromValue seems to be sufficient (see above)Anzovin

© 2022 - 2024 — McMap. All rights reserved.