c++ - QPainter 绘制线条方法

标签 c++ qt

我使用下面的代码在qt中绘制一个图的轴:

...

static const std::array<const QPointF,10*2> horizontalAxis = {
    QPointF(0.f,0.f), QPointF(1.f,0.f),
    // Horizontal scales
    QPointF(0.f,0.f), QPointF(0.f,1.f),
    QPointF(0.125f,0.f), QPointF(0.125f,1.f),
    QPointF(0.25f,0.f), QPointF(0.25f,1.f),
    QPointF(0.375f,0.f), QPointF(0.375f,1.f),
    QPointF(0.5f,0.f), QPointF(0.5f,1.f),
    QPointF(0.625f,0.f), QPointF(0.625f,1.f),
    QPointF(0.75f,0.f), QPointF(0.75f,1.f),
    QPointF(0.875f,0.f), QPointF(0.875f,1.f),
    QPointF(1.f,0.f), QPointF(1.f,1.f)
};

static const std::array<const QPointF,6*2> verticalAxis = {
    QPointF(0.f,0.f), QPointF(0.f,1.f),
    // Vertical scales
    QPointF(0.f,0.f), QPointF(-1.f,0.f),
    QPointF(0.f,0.25f), QPointF(-1.f,0.25f),
    QPointF(0.f,0.5f), QPointF(-1.f,0.5f),
    QPointF(0.f,0.75f), QPointF(-1.f,0.75f),
    QPointF(0.f,1.f), QPointF(-1.f,1.f)
};

...

void Plot::paint(QPainter& p)
{
    int const width = p.device()->width();
    int const height = p.device()->height();
    Q_ASSERT(width > xpaddingLeft + xpaddingRight);
    Q_ASSERT(height > ypaddingTop + ypaddingBottom);

    if(dirty) {
        recalculate();
    }

    p.save();

    int const bottomLeftX = xpaddingLeft;
    int const bottomLeftY = height - ypaddingBottom;
    int const scaleX = width - xpaddingLeft - xpaddingRight;
    int const scaleY = height - ypaddingTop - ypaddingBottom;

    p.setRenderHint(QPainter::HighQualityAntialiasing,false);
    p.setRenderHint(QPainter::Antialiasing,false);

    QPen pen(QBrush(QColor::fromRgb(0,0,0)), 2);
    pen.setCosmetic(true);  // Do not apply scale to the pen
    p.setPen(pen);

    // Horizontal Axis
    p.resetTransform();
    p.translate(bottomLeftX,bottomLeftY);   // Origin at bottom left
    p.scale(scaleX,scaleSize); // y-axis points down. Only scale y to match the scale-mark size
    p.drawLines(&horizontalAxis[0], (int)horizontalAxis.size());

    // Vertical Axis
    p.resetTransform();
    p.translate(bottomLeftX,bottomLeftY);
    p.scale(scaleSize,-scaleY); // y-axis points up. Only scale x to match the scale-mark size
    p.drawLines(&verticalAxis[0], (int)verticalAxis.size());

    ...
}

这会产生如下图,其中 lhs 有一个奇怪的伪像(仅显示没有加载数据的轴):
水平轴刻度导致 LHS 出现奇怪的伪影 Horizontal axis scales result in weird artifact to the LHS

注释掉水平比例定义的所有 QPointF 定义可以消除这个奇怪的工件。然而,评论任何一对单独的点似乎并不影响它。如果我不再使用 drawLines() 方法,如下所示,拉伸(stretch)就会消失。

    //p.drawLines(&horizontalAxis[0], (int)horizontalAxis.size());
    for(size_t k = 0; k < horizontalAxis.size()-1; k += 2) p.drawLine(horizontalAxis[k],horizontalAxis[k+1]);

我得到如下结果,没有任何伪影(仅显示未加载数据的轴):
水平轴刻度显示没有切换 Horizontal axes scales show no switching

我是不是遗漏了什么或者这是 drawLines() 中的错误?

我使用 drawLines() 函数两次来绘制垂直轴和实际数据(作为折线图),没有(明显的)问题,但我想更确定它不会在我无法测试的情况下导致奇怪的伪影。

最佳答案

您正在使用的 drawLines() 重载是(来自 Qt5 文档):

QPainter::drawLines (const QPointF* pointPairs, int lineCount)

请注意第二个参数。它称为 lineCount,而不是点计数,因此您必须传递一半的点数:

assert (0 == horizontalAxis.size () % 2);
p.drawLines (&horizontalAxis[0], static_cast<int> (horizontalAxis.size () / 2));

关于c++ - QPainter 绘制线条方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35520704/

相关文章:

c++ - 在类中定义时,mysql C 连接器函数不起作用

c++ - 混合多个lex/yacc组合

javascript - 如何在 C++ 中创建对象并在 QML 中访问它

qt - PyQt:如何将光标重置为任何悬停的光标

c++ - setupUi() 背后的设计原因

c++ - 遍历作为 QList<int> 的 QVariant?

c++ - 运算符在命名空间中的类之外重载

c++ - 找出由 libavcodec/h264 解码的帧中的伪影级别

c++ - 进程 qmake.exe 退出并显示代码 2 - 第一次使用 Qt 和 Qt Creator

c++ - 运行函数时控制台无输出显示