Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Why does QPainter scale (cosmetic) points in one axis although they should not be affected?



  • I'm drawing lines and points in my Qt application and having trouble with what seems like a scaling bug in QPainter. My lines work just fine but points are affected by transformations for certain scalings although the pen is set to be "cosmetic". What bothers me the most is that only a single axis (the x-axis) seems to be affected. Otherwise I could nail it down to some floating-point precision issues within the transformation/matrix code.

    Qt versions: Qt 4.8 for embedded as well as Qt 5.4 for Desktop

    Here are some renderings that should actually all look the same (like the most left one):
    alt text

    I have an RenderArea derived from QWidget which simply draws one of the images above. RenderArea is simply instantiated in main() and shown. The code is trivial there so here is the relevant painting code:

    void RenderArea::paintEvent(QPaintEvent* /* event */)
    {
        const qreal scaleFactor = 0.01;
    
        // Define a "unit" square
        std::vector<QPointF> points;
        points.push_back(QPointF(0, 0));
        points.push_back(QPointF(1.0, 0));
        points.push_back(QPointF(1.0, 1.0));
        points.push_back(QPointF(0, 1.0));
    
        // Build a scaled version of the points
        for (unsigned i = 0; i < points.size(); i++) {
            points[i] *= scaleFactor;
        }
    
        QPainter painter(this);
    
        painter.save();
    
        // Scale the painter so that every square takes 100 pixels
        // in screen space regardless of the scaleFactor:
        painter.scale(100.0 / scaleFactor, 100.0 / scaleFactor);
    
        QPen pointPen(Qt::blue, 10);
        pointPen.setCosmetic(true);
        painter.setPen(pointPen);
        painter.drawPoints(points.data(), points.size());
    
        QPen linePen(Qt::red, 5);
        linePen.setCosmetic(true);
        painter.setPen(linePen);
        painter.drawPolyline(points.data(), points.size());
    
        painter.restore();
    }
    

    The example is based on the basicdrawing example coming with Qt but I stripped everything away to highlight the problem.

    • Why does this issue arise?
    • Why does it only arise for one axis?

  • Lifetime Qt Champion

    Hi,

    Both versions are really too outdated, you should try with the current version: 5.11



  • @SGaist I reproduced it with 5.6. LTS, exactly same behavior there.

    To reproduce: Simply copy the code above into the "Examples\Qt-YOUR-VESION\widgets\painting\basicdrawing" example.

    My problem is that this example is extremely basic so I see only a few possibilities:

    • My code is wrong. I can't find a problem in those few lines of code, can anyone else?
    • It's a Qt bug. Then this just has to be reported somewhere in the past since it seems to exist for so long now. Does anybody know a bug like this? I only found a few problems "on mac" etc. but not related to such platform-independent problem.

    And even if no one knows the answer to any of my questions: How would you write code that is capable to render very small and very big ranges of values. The transformation code seems the correct way to do it but maybe I'm not aware of other possibilities?


  • Lifetime Qt Champion

    Again, 5.6, is outdated, 5.11 is the current stable version with 5.12 being around the corner.




Log in to reply