Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

QDoubleSpinBox with leading zeros (always 4 digits)

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?

like image 814
Horst Walter Avatar asked Oct 23 '14 21:10

Horst Walter


2 Answers

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.

like image 129
Blueman Avatar answered Nov 20 '22 13:11

Blueman


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.

like image 38
Iuliu Avatar answered Nov 20 '22 14:11

Iuliu