Qt Forum

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Unsolved

    Solved Issues setting value of QDoubleSpinBox after connecting

    General and Desktop
    3
    3
    590
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • D
      deleted546 last edited by

      valuesetter.h:

      #ifndef VALUESETTER_H
      #define VALUESETTER_H
      
      #include <QSlider>
      #include <QSpinBox>
      #include <QWidget>
      #include <memory>
      
      namespace Ui {
      class ValueSetter;
      }
      
      class ValueSetter : public QWidget
      {
          Q_OBJECT
      
      public:
          explicit ValueSetter(QWidget *parent = nullptr);
          ~ValueSetter();
      
          void dpi(int dpi);
          void setValue(int value);
          void setDoubleValue(double value);
          void setMinimum(int minimum);
          void setMaximum(int maximum);
      
      signals:
          void valueChanged(int);
          void valueChangedDouble(double);
          void minimumChanged(int);
          void maximumChanged(int);
      
      private:
          double round2(double val);
          int val, min, max;
      
          int Dpi=72;
          Ui::ValueSetter *ui;
      };
      
      #endif // VALUESETTER_H
      

      valuesetter.cpp:

      #include "valuesetter.h"
      #include "ui_valuesetter.h"
      
      #include <QHBoxLayout>
      #include <QVBoxLayout>
      #include <string>
      #include <QtMath>
      #include <QDebug>
      
      ValueSetter::ValueSetter(QWidget *parent) :
          QWidget(parent),
          ui(new Ui::ValueSetter)
      {
          ui->setupUi(this);
          setValue(0); setMinimum(0); setMaximum(1000*Dpi);
          connect(ui->slider,&QSlider::valueChanged,this,&ValueSetter::setValue);
          connect(ui->spinbox,static_cast<void (QDoubleSpinBox::*)(double)>(&QDoubleSpinBox::valueChanged),
                  this,&ValueSetter::setDoubleValue);
      }
      
      ValueSetter::~ValueSetter()
      {
          delete ui;
      }
      
      void ValueSetter::setValue(int value)
      {
          qDebug() << ui->spinbox->maximum() << round2(round2(value)/round2(Dpi));
          ui->spinbox->setValue(round2(round2(value)/round2(Dpi)));
          ui->slider->setValue(value);
          emit valueChanged(value);
      }
      
      void ValueSetter::setDoubleValue(double value)
      {
          ui->spinbox->setValue(value); ui->slider->setValue(static_cast<int>(value*Dpi));
          emit valueChangedDouble(value);
      }
      
      void ValueSetter::setMinimum(int min)
      {
          ui->spinbox->setMinimum(static_cast<double>(min)/Dpi); ui->slider->setMinimum(min);
          emit minimumChanged(min);
      }
      
      void ValueSetter::setMaximum(int max)
      {
          ui->spinbox->setMaximum(static_cast<double>(max)/Dpi); ui->slider->setMaximum(max); emit maximumChanged(max);
      }
      
      double ValueSetter::round2(double val)
      {
          double value = static_cast<int>(100*val+0.5);
          return static_cast<double>(value/100);
      }
      

      valuesetter.ui:
      ValueSetterWidgets.png ValueSetterUI.png

      In short, my problem is that when I try to move the QSlider, I get this set of errors, which I have a hard time resolving:
      ValueSetterDebug.png

      At first, the round2 in my valuesetter.cpp class was simply static_cast<double>. My guess was to test whether the error remained when I made sure there were only 2 decimal places, and it did. I don't think I implemented connect wrong, as there were no compiler errors or anything.

      So I need help debugging.

      1 Reply Last reply Reply Quote 0
      • Christian Ehrlicher
        Christian Ehrlicher Lifetime Qt Champion last edited by

        I would guess it's a stack overflow since QDoubleSpinBox::setValue() triggers QSlider::valueChanged. Take a look at the next calls by clicking on '<More>' and you'll see it.

        Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
        Visit the Qt Academy at https://academy.qt.io/catalog

        1 Reply Last reply Reply Quote 2
        • hskoglund
          hskoglund last edited by

          Yes as @Christian-Ehrlicher says, it's overflowing :-( because the signals you connect to (the 2 valueChanged()) can be triggered either by a human clicking on the slider or the spinbox, or by your C++ code doing a ->setValue().

          So when you drag the slider, your code sets a new value for the slider, which then sets a new value for the slider, etc etc in a forever loop :-(

          One workaround is to neuter/silence the sliders/spinbox so that they only emit signals when a human clicks, not for C++ code. You can use the blockSignals(true) and blockSignals(false) for that, say like this:

          ...
          void ValueSetter::setValue(int value)
          {
              qDebug() << ui->spinbox->maximum() << round2(round2(value)/round2(Dpi));
           
              ui->spinbox->blockSignals(true);
              ui->spinbox->setValue(round2(round2(value)/round2(Dpi)));
              ui->spinbox->blockSignals(false);
          
              ui->slider->blockSignals(true);
              ui->slider->setValue(value);
              ui->slider->blockSignals(false);
          
              emit valueChanged(value);
          }
          ...
          1 Reply Last reply Reply Quote 2
          • First post
            Last post