1

I've created a vector v with 128 elements from -3000 to 3000 and I want to associate it to a QDoubleSpinBox and a QSlider, because dividing 6000 to 128 and setting the QDoubleSpinBox we have always the round problem. So can we set the range and the stepsize both to a QDoubleSpinBox and QSlider with a vector like this?

  std::vector<double> v(128);

  for (int i = 0; i < 128; ++i)
  {
      v[i] = -3000.0 + 6000.0 * (i) / 127.0;
  }
SamuelNLP
  • 4,038
  • 9
  • 59
  • 102
  • It's not obvious what you are trying to achieve. What do the `QDoubleSpinBox` and `QSlider` represent, and how do they relate to each other? – cmannett85 Sep 04 '12 at 16:50

2 Answers2

2

QSlider only operates with int steps, so you'd just need to do the calculation yourself:

#include <QtGui>
#include <cmath>

class MyWidget : public QWidget {
  Q_OBJECT

public:
  MyWidget() : QWidget() {
    slider_ = new QSlider;
    slider_->setRange(0, 127);
    connect(slider_, SIGNAL(valueChanged(int)), SLOT(ChangeSpinBox(int)));

    box_ = new QDoubleSpinBox;
    box_->setRange(-3000.0, 3000.0);
    connect(box_, SIGNAL(valueChanged(double)), SLOT(ChangeSlider(double)));

    QVBoxLayout *layout = new QVBoxLayout;
    layout->addWidget(slider_);
    layout->addWidget(box_);

    setLayout(layout);
  }
private slots:
  void ChangeSpinBox(int sliderValue) {
    if (convertSpinBoxValueToSlider(box_->value()) != sliderValue) {
        box_->setValue((6000.0 * sliderValue / 127.0) - 3000.0);
    }
  }

  void ChangeSlider(double spinBoxValue) {
    slider_->setValue(convertSpinBoxValueToSlider(spinBoxValue));
  }

private:
  QSlider *slider_;
  QDoubleSpinBox *box_;

  static int convertSpinBoxValueToSlider(double value) {
    return qRound((value + 3000.0) * 127.0 / 6000.0);
  }

};

int main(int argc, char **argv) {
  QApplication app(argc, argv);
  MyWidget w;
  w.show();
  return app.exec();
}

#include "main.moc"

Or am I not understanding your question?

Dave Mateer
  • 17,608
  • 15
  • 96
  • 149
  • the problem will be when editing the QSpinBox and I put there a number that is not one of the 128 numbers that would be on the vector. – SamuelNLP Sep 05 '12 at 08:37
  • Yes, you would have to set some kind of fuzzy logic in there to not change the spin box if it is with the same range. I edited my code to support that. – Dave Mateer Sep 05 '12 at 12:39
  • I don't understand one thing. Spinbox has up/down arrows. How is that supposed to work in this solution, when step size is out of double precision? – Pavel Zdenek Sep 06 '12 at 20:59
0

First of all, you have a bug in your vector computation. If you want to divide a range to X parts, then your vector must be of size X+1 not X. Example: you want to split range 0-10 to 5 parts. How many items you need? Your code suggests 5. But the answer is [0,2,4,6,8,10] = 6. So have vector 129 and do the division by 128.

So you would like to have a step size of 6000/128 = 48.875 exactly. You can do that with QDoubleSpinBox

QDoubleSpinBox::setRange(-3000.0,3000.0);
QDoubleSpinBox::setSingleStep(48.875);

but not with QSlider which takes only integer. You can avoid the rounding error by multiplying your range by 1000.

QSlider::setRange(-3000000,3000000);
QSlider::setSingleStep(48875);

For setting the selected result to the spinbox, you need to divide by 1000 again of course.

Pavel Zdenek
  • 7,146
  • 1
  • 23
  • 38
  • I want a vector with 128 elements, so the 0 also counts. – SamuelNLP Sep 05 '12 at 08:43
  • If you want a vector with 128 elements and have both -3000 and +3000 in the vector, then you are dividing 6000 by 127 not 128 and your step size is 47.244094488188976377952755905512 which means that the multiplication by 1000 won't work. – Pavel Zdenek Sep 05 '12 at 09:07
  • That's my problem. that's why using a vector instead of a stepsize would solve my problem, but since it is not possible to use one. – SamuelNLP Sep 05 '12 at 10:28