Проблема слияния цветов при рисовании эллипсов над линиями в Qt - PullRequest
1 голос
/ 14 мая 2019

Я разрабатываю небольшое приложение, похожее на художника. Мне бы хотелось, чтобы в моем приложении была функция, которая позволяла бы пользователю рисовать точки, а затем связывать их линиями в том порядке, в котором они были нарисованы. Я также хочу, чтобы мои точки были нарисованы выше линий. Вот как я пытаюсь добиться этого:

 void ImageViewer::on_linesAct_triggered()
{
    QPainter paint(objectpix);
    QPen LinePen (QColor(255-pointcolor[currentset-1].red(),255-pointcolor[currentset-1].green(),255-pointcolor[currentset-1].blue()));
    LinePen.setWidth(5);

    for(int i=0;i<count[currentset-1]-1;i++)
    {
        paint.setPen(LinePen);
        QPoint p1(static_cast<int>(round(tableX[i][currentset-1])),static_cast<int>(round(tableY[i][currentset-1])));
        QPoint p2(static_cast<int>(round(tableX[i+1][currentset-1])), static_cast<int>(round(tableY[i+1][currentset-1])));
        paint.drawLine(p1,p2);
        paint.setPen(QPen(pointcolor[currentset-1]));
        paint.setBrush(QBrush(pointcolor[currentset-1],Qt::SolidPattern));
        paint.drawEllipse(p1,2,2);
        paint.drawEllipse(p2,2,2);
    }

    /...
}

Работает так, как задумано, за исключением того факта, что цвета линий и точек как бы сливаются (не уверен в номенклатуре) вместе. Картинка внизу иллюстрирует проблему. enter image description here Есть идеи о возможном решении?

Ответы [ 2 ]

1 голос
/ 14 мая 2019

Если учесть список пунктов [A, B, C, D] и ваш код:

  • Итерация 1: p1 = A, p2 = B

    • Провести линию между А и В
    • Нарисовать эллипс в точках A и B
  • Итерация 2: p1 = B, p2 = C

    • Провести линию между B и C <- нарисует над эллипсом в B </li>
    • Рисовать эллипс в B и C <- Повторно нарисовать эллипс в B </li>
  • Итерация 3: p1 = C, p2 = D

    • Провести линию между C и D <- нарисует над эллипсом в C </li>
    • Рисовать эллипс в C и D <- Повторно нарисовать эллипс в C </li>

Вы рисуете свои эллипсы дважды с началом линии между ними. То, что вы можете видеть, это артефакты из-за псевдонимов (как упомянуто в другом ответе) и первого эллипса, нарисованного ниже второй линии.

Самый простой способ добиться этого - использовать два цикла:

class MyWidget: public QWidget
{
public:
    MyWidget(): QWidget()
    {}
    virtual void paintEvent(QPaintEvent* ev) override
    {
        QVector<QPoint> pointcolor;
        pointcolor << QPoint(10, 12) << QPoint(40, 60) << QPoint(70, 20) << QPoint(100, 100);
        QPainter paint(this);
        paint.setRenderHint(QPainter::Antialiasing);
        QPen LinePen (Qt::red);
        LinePen.setWidth(5);

        for(int i = 1;i != pointcolor.length();++i)
        {
            paint.setPen(LinePen);
            QPoint p1 = pointcolor.at(i - 1);
            QPoint p2 = pointcolor.at(i);
            paint.drawLine(p1,p2);
        }

        // Draw the points above the lines
        paint.setPen(Qt::green);
        paint.setBrush(Qt::green);
        for(QPoint const& point: pointcolor)
        {
            paint.drawEllipse(point,2,2);
        }
    }
};
1 голос
/ 14 мая 2019

Я думаю, вы могли бы попытаться установить подсказку рендеринга для художника, используя QPainter::setRenderHint, что-то вроде:

QPainter paint(objectpix);
paint.setRenderHint(QPainter::Antialiasing);
...