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.8k 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.
  • D Offline
    D Offline
    dnadave
    wrote on last edited by
    #1

    How can I set the display precision separate from the internal precision of the value in a QDoubleSpinBox? If I use setDecimals, it changes the internal precision such that setDecimals(4) changes value from 1.12345 to 1.1235. This ruins the numerical stability of some code I have.

    I also don't want to have 1.12345 displayed in the spinbox, but rather something like 1.123.

    Thanks!!

    Dave H

    1 Reply Last reply
    0
    • F Offline
      F Offline
      Franzk
      wrote on last edited by
      #2

      How would you expect to control the numerical stability if you have two different representations, but the results are always coming from string conversions?

      "Horse sense is the thing a horse has which keeps it from betting on people." -- W.C. Fields

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

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

        Not two different representations, but something like a printf conversion for display only. Is there something like printf for the QDoubleSpinBox display?

        1 Reply Last reply
        0
        • S Offline
          S Offline
          stukdev
          wrote on last edited by
          #4

          I don't understand what is the problem from 1.12345 to 1.1235 is round up.
          What mean ruins the numerical stability of your code?

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

            So, the client for whom I'm doing this work wants the display to real 10 when the value is 10.00001. What happens now is the SpinBox is displaying 10.00001. If I call setDecimals with some value, say 3, then the underlying value is rounded to three significant digits. So, setDecimals changes the precision of the underlying value, ruining the numerical stability of the algorithm, and does not just affect the display precision.

            What I need is a way to change only the display precision and keep the underlying value unchanged.

            1 Reply Last reply
            0
            • 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