Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-29764

QSlider handle disappears in big QSlider

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Unresolved
    • Icon: P3: Somewhat important P3: Somewhat important
    • None
    • 4.7.0, 4.8.0, 5.0.0
    • None
    • Windows, Linux and Mac Os X
    • macOS

      My program uses big QSlider (from 700 pixels to 36000 pixels, maybe more. And I know widget max pixel size is something like 0XFFFFF0 pixels)
      I observed a strange behavior with slider handle rendering with big QSlider.

      Sometime slider handle just disappears after passing some position (using mouse or arrow keys), sometime slider handle "loop-back" to a pseudo-random position.
      This problem is "only" a rendering graphics problem : QSlider internal value is still correct.

      I investigated and found the reason.
      In QStyle::sliderPositionFromValue(), implementation precision fluctuates depending on parameters values.

      Depending on QSlider min, max and span values, QStyle::sliderPositionFromValue() returned value is limited in some different ways.
      See my comments for the 3 cases of QStyle::sliderPositionFromValue() returned value computation :

       
      int QStyle::sliderPositionFromValue(int min, int max, int logicalValue, int span, bool upsideDown)
      {
          if (span <= 0 || logicalValue < min || max <= min)
              return 0;
          if (logicalValue > max)
              return upsideDown ? span : min;
          uint range = max - min;
          uint p = upsideDown ? max - logicalValue : logicalValue - min;
          if (range > (uint)INT_MAX/4096) {
              double dpos = (double(p))/(double(range)/span);
              return int(dpos);
      
              // case 1/ => computed with double precision :
              // returned max value is INT_MAX
          } else if (range > (uint)span) {
              return (2 * p * span + range) / (2*range);
      
              // case 2/ computed with uint precision :
              // (2 * p * span + range) < UINT_MAX
              // returned max value is (UINT_MAX - range) / (2 * range)
          } else {
              uint div = span / range;
              uint mod = span % range;
              return p * div + (2 * p * mod + range) / (2 * range);
      
              // case 3/ => computed with int precision :
              // (p * div + (2 * p * mod + range)) < INT_MAX
              // returned max value is INT_MAX - (2 * range * mod + range) / range
          }
          // equiv. to (p * span) / range + 0.5
          // no overflow because of this implicit assumption:
          // span <= 4096
      }
      

      The bigger the range is, the bigger the return can be (case 1/)
      I found this bug in qt 4.7 and qt 4.8. I think it is still there in qt 5.0, according to http://qt.gitorious.org

        No reviews matched the request. Check your Options in the drop-down menu of this sections header.

            Unassigned Unassigned
            franck.bonin franck bonin
            Votes:
            4 Vote for this issue
            Watchers:
            7 Start watching this issue

              Created:
              Updated:

                There are no open Gerrit changes