为什么QPainter::drawPoint画一条水平线段?

2023-12-25

我正在尝试绘制一个 3 像素大点QPainter。但下面的代码却绘制了一条宽度为 3 个像素的水平线。

#include <QPainter>
#include <QImage>

int main()
{
    const int w=1000, h=1000;
    QImage img(w, h, QImage::Format_RGBX8888);
    {
        QPainter p(&img);
        p.fillRect(0,0,w,h,Qt::black);
        p.scale(w,h);
        p.setPen(QPen(Qt::red, 3./w, Qt::SolidLine, Qt::RoundCap));
        p.drawPoint(QPointF(0.1,0.1));
    }
    img.save("test.png");
}

这是生成图像的左上角:

我期望得到一个红色圆圈的点,或者至少是一个正方形,但我得到的是这条线段。如果我评论掉p.scale(w,h)并绘制宽度的点3(代替3./w) 在位置(100,100),然后我得到一个高度和宽度基本对称的小 3 像素点。

这是怎么回事?为什么我得到的是线段而不是预期的点?以及如何解决这个问题,而不需要绘制椭圆或避免QPainter::scale?

我在 Linux x86 上使用 Qt 5.10.0 和 g++ 5.5.0。 Qt 5.5.1 上也会发生同样的情况。


看起来QPaintEngineEx::drawPoints将点渲染为长度的线段1/63.。请参阅以下代码qtbase/src/gui/painting/qpaintengineex.cpp http://code.qt.io/cgit/qt/qtbase.git/tree/src/gui/painting/qpaintengineex.cpp#n846在 Qt 源中:

void QPaintEngineEx::drawPoints(const QPointF *points, int pointCount)
{
    QPen pen = state()->pen;
    if (pen.capStyle() == Qt::FlatCap)
        pen.setCapStyle(Qt::SquareCap);

    if (pen.brush().isOpaque()) {
        while (pointCount > 0) {
            int count = qMin(pointCount, 16);
            qreal pts[64];
            int oset = -1;
            for (int i=0; i<count; ++i) {
                pts[++oset] = points[i].x();
                pts[++oset] = points[i].y();
                pts[++oset] = points[i].x() + 1/63.;
                pts[++oset] = points[i].y();
            }
            QVectorPath path(pts, count * 2, qpaintengineex_line_types_16, QVectorPath::LinesHint);
            stroke(path, pen);
            pointCount -= 16;
            points += 16;
        }
    } else {
        for (int i=0; i<pointCount; ++i) {
            qreal pts[] = { points[i].x(), points[i].y(), points[i].x() + qreal(1/63.), points[i].y() };
            QVectorPath path(pts, 2, 0);
            stroke(path, pen);
        }
    }
}

注意pts[++oset] = points[i].x() + 1/63.;不透明画笔分支中的线。这是路径的第二个顶点 - 相对于点的所需位置移动。

这解释了为什么该线延伸到所请求位置的右侧以及为什么它取决于比例。所以,对于理想的情况来说,OP中的代码似乎并没有错QPainter实现,但刚刚遇到了 Qt 错误(无论是在方法的实现中还是在其文档中)。

所以结论:一has要解决这个问题,可以使用不同的比例,或者绘制椭圆,或者绘制比实际长度小得多的线段QPainter::drawPoints does.

我已将此报告为QTBUG-70409 https://bugreports.qt.io/browse/QTBUG-70409.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么QPainter::drawPoint画一条水平线段? 的相关文章

随机推荐