Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Set display precision different from internal precision in QDoubleSpinBox
Forum Updated to NodeBB v4.3 + New Features

Set display precision different from internal precision in QDoubleSpinBox

Scheduled Pinned Locked Moved General and Desktop
17 Posts 7 Posters 14.9k Views 2 Watching
  • 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.
  • S Offline
    S Offline
    stukdev
    wrote on last edited by
    #6

    So you want use two different representations, one your value 10.000000000001 and one the display 10
    So create a function convert/deconvert to display your personal value and pass to SpinBox...

    1 Reply Last reply
    0
    • G Offline
      G Offline
      goetz
      wrote on last edited by
      #7

      I as a user would drive nuts, if the displayed value of "10" is actually "translated" to a value of "10.0000001" or "10" for the application, depending on the source of the "10" (rounded set-value in the first case, user typed-in in the latter).

      I consider this bad user experience and programming style...

      An no, it is not just a case of printf. The spinbox is an input element, not just a fancy display. Naturally, the entered value is exactly represented internally.

      http://www.catb.org/~esr/faqs/smart-questions.html

      1 Reply Last reply
      0
      • A Offline
        A Offline
        andre
        wrote on last edited by
        #8

        Actually, I would not be too sure that when using a Double, 10 isn't just 10.000000001 anyway. I would display the precision you are going to use the number with. That is, if the 10th decimal is relevant for your algorithm, make sure you display it.

        What I would do (and should do for my own purposes as well, thanks for reminding me), is make a QDoubleSpinbox that has an extra button or dropdown or something that you use to control the precision. That makes it easy to use the spinbox with the set precision, but also possible to change to a higher precision if needed.

        1 Reply Last reply
        0
        • B Offline
          B Offline
          baysmith
          wrote on last edited by
          #9

          You can set the decimals property to a large value to prevent it from rounding and then use textFromValue(double) to display the number in your own way. I use it to create a spin box which displays using the 'g' format. Since the sizeHint is based upon the decimals property, it must also be adjusted.

          Here is the idea. (The code below is incomplete.)
          @
          class DoubleSpinBox : public QDoubleSpinBox
          {
          public:
          explicit DoubleSpinBox(QWidget *parent = 0);
          virtual QString textFromValue();
          virtual QSize sizeHint() const;
          };
          @

          @
          DoubleSpinBox::DoubleSpinBox(QWidget *parent)
          {
          // Save default sizeHint before changing decimal property
          cachedSizeHint = QDoubleSpinBox::sizeHint();

          // Set decimals to large value since QDoubleSpinBox rounds
          // with QString::number(value, 'f', decimals).toDouble()
          QDoubleSpinBox::setDecimals(std::numeric_limits<double>::max_exponent);
          

          }

          QString DoubleSpinBox::textFromValue(double value) const
          {
          return QString::number(value, 'g', std::numeric_limits<double>::digits10);
          }

          QSize DoubleSpinBox::sizeHint() const
          {
          return cachedSizeHint;
          }

          @

          Nokia Certified Qt Specialist.

          1 Reply Last reply
          0
          • D Offline
            D Offline
            dnadave
            wrote on last edited by
            #10

            Volker, I understand where you are coming from. The application has three spinboxes, say a, b , and c. The user can input parameters into any one of the three. If the user inputs a parameter into spinbox a, some calculations are done and the values in spinboxes b and c are are updated. What is happening is that the calculations are off if I use setDecimal and set its integer value to something reasonable for display. This is why I'm asking if there is something like printf.

            From what I think I understand is going on, it sounds like the private member value is an unadulturated double. The member function value() returns value rounded to the precision set with setDecimal. This may be where the problem is. If this is the case, without subclassing QDoubleSpinBox, is there a way to access value in its unadulturated form?

            1 Reply Last reply
            0
            • B Offline
              B Offline
              baysmith
              wrote on last edited by
              #11

              No, there is no member value with an unadulterated double. The value is rounded in setValue() before it is stored.

              Nokia Certified Qt Specialist.

              1 Reply Last reply
              0
              • D Offline
                D Offline
                dnadave
                wrote on last edited by
                #12

                Bradley, I saw your reply just after I sent mine in. Thanks for the code. I'm thinking that subclassing might be the only way to go.

                So, just to be sure, setValue() is called when setDecimals() has been called and value() is called to display the value in the SpinBox? I.e. setDecimal(4) leads to something like setValue( round( value() , 4 ) ) in order to display the value in the spinbox?

                1 Reply Last reply
                0
                • B Offline
                  B Offline
                  baysmith
                  wrote on last edited by
                  #13

                  Below is the source for setDecimals() and setValue(). Yes, calling setDecimals() calls setValue(value()) and in setValue(), round(value) is called which uses the decimals property to round the number.

                  @
                  void QDoubleSpinBox::setDecimals(int decimals)
                  {
                  Q_D(QDoubleSpinBox);
                  d->decimals = qBound(0, decimals, DBL_MAX_10_EXP + DBL_DIG);

                  setRange(d->actualMin, d->actualMax); // make sure values are rounded
                  setValue(value());
                  

                  }

                  void QDoubleSpinBox::setValue(double value)
                  {
                  Q_D(QDoubleSpinBox);
                  QVariant v(d->round(value));
                  d->setValue(v, EmitIfChanged);
                  }
                  @

                  Nokia Certified Qt Specialist.

                  1 Reply Last reply
                  0
                  • P Offline
                    P Offline
                    Peppy
                    wrote on last edited by
                    #14

                    Some kind of Validator/Placeholder
                    f.e.: "QDoubleValidator":http://doc.qt.nokia.com/latest/qdoublevalidator.html
                    or QRegExpValidator ??

                    1 Reply Last reply
                    0
                    • D Offline
                      D Offline
                      dnadave
                      wrote on last edited by
                      #15

                      Wow! That's crazy! Why would you do that?

                      To me, I was expecting setDecimals() to behave much like the iostream modifiers, and not to change the underlying value. This should be documented somewhere as I doubt it is the expected behavior from reading the documentation.

                      Looks like I'll have to subclass QDoubleSpinBox...

                      1 Reply Last reply
                      0
                      • B Offline
                        B Offline
                        baysmith
                        wrote on last edited by
                        #16

                        From http://doc.qt.nokia.com/4.7/qdoublespinbox.html#details

                        bq. Note: QDoubleSpinBox will round numbers so they can be displayed with the current precision. In a QDoubleSpinBox with decimals set to 2, calling setValue(2.555) will cause value() to return 2.56.

                        Nokia Certified Qt Specialist.

                        1 Reply Last reply
                        0
                        • P Offline
                          P Offline
                          Peppy
                          wrote on last edited by
                          #17

                          You can hack it!

                          Set up decimals to 4, but allows placing just 3, so it shouldn't round value...I think :)

                          1 Reply Last reply
                          0

                          • Login

                          • Login or register to search.
                          • First post
                            Last post
                          0
                          • Categories
                          • Recent
                          • Tags
                          • Popular
                          • Users
                          • Groups
                          • Search
                          • Get Qt Extensions
                          • Unsolved