PDA

View Full Version : QDoubleSpinBox with nonlinear values



code_err
20th February 2012, 14:45
I would like to create spinBox which would have a concrete list of values with alternating interval beetwen positions on it.

Something like that: 1.0, 5.0, 20.0, 35.0, 37.0, 39.0, 44.0, 50.0...

Is there a simple way to do it?

thomas@itest
20th February 2012, 18:55
Hi !

You must reimplement virtual void QAbstractSpinBox::stepBy(int steps) (http://doc.qt.nokia.com/4.7/qabstractspinbox.html#stepBy)

Here's a functionnal example :


#ifndef MYSPINBOX_H
#define MYSPINBOX_H

#include <QDoubleSpinBox>

class MySpinBox : public QDoubleSpinBox
{
Q_OBJECT
public:
explicit MySpinBox(QWidget *parent = 0) : QDoubleSpinBox(parent)
{
_values<<1.0<<5.0<<20.0<<35.0<<37.0<<39.0<<44.0<<50.0;
setRange(_values.first(),_values.last());
}

void stepBy(int steps)
{
int idx = findIdx(value());
idx += steps>0 ? 1:-1;
setValue(_values.value(idx));
}

private:
QList<double> _values;

int findIdx(double currVal)
{
for(int idx = 0 ; idx < _values.count()-1 ; ++idx)
if(currVal>=_values.value(idx) && currVal<_values.value(idx+1)) return idx;

return _values.count()-1;
}
};

#endif // MYSPINBOX_H


... my first answer on this forum ! ...

code_err
21st February 2012, 01:16
Wow, it looks great. I can't write such an concise and elegant code so far. Thanks.

norobro
21st February 2012, 02:45
A couple of comments, if I may:

1. Qt provides a lookup function for QList: QList::indexOf()

2. But, the lookup is unnecessary if you make idx a member variable and increment it:
class MySpinBox : public QDoubleSpinBox
{
Q_OBJECT
public:
explicit MySpinBox(QWidget *parent = 0) : QDoubleSpinBox(parent), _idx(0)
{
values<<1.0<<5.0<<20.0<<35.0<<37.0<<39.0<<44.0<<50.0;
setRange(values.first(),values.last());
}

void stepBy(int steps)
{
_idx += steps;
setValue(_values.at(_idx));
}

private:
QList<double> _values;
int _idx;
};

Hope this helps!

ChrisW67
21st February 2012, 06:47
Range checking/clamping of idx might be a good idea. Crashes in debug mode if you Shift-PgUp for example. Doesn't crash in release mode but fails to operate correctly for me: e.g. press Shift-PgUp and then up arrow and you run through:


//_idx _value.at(_idx)
10 6.71656e-317
11 3.95253e-323
12 6.71634e-317
13 4.44659e-323
14 3.21143e-322
15 6.95315e-310
16 4.88059e-313

where the index and data are rubbish. The up-arrow does not appear to function any longer and down remains unavailable.

norobro
21st February 2012, 21:07
You're right Chris. I just "winged it" on this one as evidenced by the values/_values typo.

Revised:
class MySpinBox : public QDoubleSpinBox
{
Q_OBJECT
public:
explicit MySpinBox(QWidget *parent = 0) : QDoubleSpinBox(parent), _idx(0)
{
_values<<1.0<<5.0<<20.0<<35.0<<37.0<<39.0<<44.0<<50.0;
setRange(_values.first(),_values.last());
}

void stepBy(int steps)
{
_idx += steps;
if(_idx<0) _idx=0;
else if(_idx>=_values.count()) _idx=_values.count()-1;
setValue(_values.at(_idx));
}

private:
QList<double> _values;
int _idx;
};