Отрисовка графических примитивов

Последнее обновление: 14.01.2024

Рисование линиий

Для отрисовки линии QPainter применяет метод drawLine(), который имеет ряд версий:

void QPainter::drawLine(const QLineF &line)
void QPainter::drawLine(const QLine &line)
void QPainter::drawLine(const QPoint &p1, const QPoint &p2)
void QPainter::drawLine(const QPointF &p1, const QPointF &p2)
void QPainter::drawLine(int x1, int y1, int x2, int y2)

В метод может передаваться объект линиии - QLine/QLineF, две точки QPointF/QPoint, между которыми строится линия, либо 4 координаты. Для примера возьмем последний вариант:

#include <QApplication>
#include <QWidget>
#include <QPainter>

class MyWidget : public QWidget
{
    void paintEvent(QPaintEvent *event)
    {
        QPainter painter;
        painter.begin(this);
        painter.drawLine(10, 50, 150, 50);
        painter.end();
    }
};

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    MyWidget widget;
    widget.setFixedSize(250, 150);
    widget.setWindowTitle("METANIT.COM");

    widget.show();
    return app.exec();
}

Здесь рисуется линия, для которой начальная точка имеет координаты X=10, Y=50, а конечная точка - координаты X=150, Y=50

Отрисовка линии в виджетах Qt

Отрисовка нескольких линий:

class MyWidget : public QWidget
{
    void paintEvent(QPaintEvent *event)
    {
        QPainter painter;
        painter.begin(this);
        painter.drawLine(10, 30, 150, 30);
        painter.drawLine(150, 30, 150, 120);
        painter.drawLine(150, 120, 10, 120);
        painter.drawLine(10, 120, 10, 30);
        painter.end();
    }
};
QPainter и Отрисовка линий в виджетах Qt

Отрисовка прямоугольников

Для отрисовки прямоугольников QPainter предоставляет метод drawRect():

void QPainter::drawRect(const QRectF &rectangle)
void QPainter::drawRect(int x, int y, int width, int height)
void QPainter::drawRect(const QRect &rectangle)

В метод передатется либо объект QRect/QRectF, который определяет прямоугольную область, либо x- и y-координаты верхнего левого угла прямоугольника и его ширина и высота:

class MyWidget : public QWidget
{
    void paintEvent(QPaintEvent *event)
    {
        QPainter painter;
        painter.begin(this);
        // x=50, y=40, ширина = 100, высота = 50
        painter.drawRect(50, 40, 100, 50);
        painter.end();
    }
};

Также в классе QPainter определен специальный метод для создания приямоугольника с закругленными углами - drawRoundedRect():

void drawRoundedRect(const QRectF &rect, qreal xRadius, qreal yRadius, Qt::SizeMode mode = Qt::AbsoluteSize)
void drawRoundedRect(int x, int y, int w, int h, qreal xRadius, qreal yRadius, Qt::SizeMode mode = Qt::AbsoluteSize)
void drawRoundedRect(const QRect &rect, qreal xRadius, qreal yRadius, Qt::SizeMode mode = Qt::AbsoluteSize)

Здесь дополнительно передаются параметры xRadius и yRadius, которые устанавливают соответственно радиус закругления по оси X и Y. А последний параметр - mode указывает, как будут интепретироваться значения радиусов - как абсолютные значения (Qt::AbsoluteSize) или как процентные значения относительно ширины и высоты прямоугольника (Qt::RelativeSize)

class MyWidget : public QWidget
{
    void paintEvent(QPaintEvent *)
    {
        QRectF rectangle(10.0, 20.0, 120.0, 80.0);

        QPainter painter(this);
        painter.drawRoundedRect(rectangle, 20.0, 15.0);
    }
};
прямоугольник с закругленными углами в Qt

Соединение точек

Для отриовки линии, которая соединяет несколько точек, применяется метод drawPolyline():

void QPainter::drawPolyline(const QPointF *points, int pointCount)
void QPainter::drawPolyline(const QPolygonF &points)
void QPainter::drawPolyline(const QPoint *points, int pointCount)
void QPainter::drawPolyline(const QPolygon &points)

В метод передается массив точек с количеством точек либо объекты QPolygonF. Например:

class MyWidget : public QWidget
{
    void paintEvent(QPaintEvent *)
    {
        QPainter painter;
        painter.begin(this);
        painter.drawPolyline({QPointF(120, 20), QPointF(220, 130), QPointF(20, 130)});
        painter.end();
    }
};
Отрисовка точек, соединенных линиями и метод drawPolyline в виджетах Qt

Отрисовка многоугольника

Для отрисовки многоугольника применяется метод drawPolygon():

void QPainter::drawPolygon(const QPointF *points, int pointCount, Qt::FillRule fillRule = Qt::OddEvenFill)
void QPainter::drawPolygon(const QPolygonF &points, Qt::FillRule fillRule = Qt::OddEvenFill)
void QPainter::drawPolygon(const QPoint *points, int pointCount, Qt::FillRule fillRule = Qt::OddEvenFill)
void QPainter::drawPolygon(const QPolygon &points, Qt::FillRule fillRule = Qt::OddEvenFill)

В качестве первого параметра передается массив точек или объект QPolygon. Последний параметр определяет алгоритм заполнения фигуры.

class MyWidget : public QWidget
{
    void paintEvent(QPaintEvent *)
    {
        QPainter painter;
        painter.begin(this);
        painter.drawPolygon({QPointF(120, 20), QPointF(220, 130), QPointF(20, 130)});
        painter.end();
    }
};
Отрисовка многоугольника и метод drawPolygon в виджетах Qt

Можно заметить, что в данном случае в метод передается объект QPolygonF с тем же набором точек, что и в предыдущем примере с drawPolyline(), только теперь последняя точка соединяется с первой.

Отрисовка овала/окружности

Для отрисовки овалов/окружностей применяется метод drawEllipse()

void QPainter::drawEllipse(const QRectF &rectangle)
void QPainter::drawEllipse(const QRect &rectangle)
void QPainter::drawEllipse(const QPointF ¢er, qreal rx, qreal ry)
void QPainter::drawEllipse(const QPoint ¢er, int rx, int ry)
void QPainter::drawEllipse(int x, int y, int width, int height)

В метод передается набоп значений для определения прямоугольной области, которая будет определять границы овала. Например, применим последнюю версию:

class MyWidget : public QWidget
{
    void paintEvent(QPaintEvent *)
    {
        QPainter painter;
        painter.begin(this);
        painter.drawEllipse(10, 10, 80, 80);

        painter.drawEllipse(100, 10, 80, 60);
        painter.end();
    }
};

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

Отрисовка окружностей и метод drawEllipse в виджетах Qt

Рисование дуги

Для отрисовки дуг применяется метод drawArc():

void drawArc(const QRectF &rectangle, int startAngle, int spanAngle)
void drawArc(const QRect &rectangle, int startAngle, int spanAngle)
void drawArc(int x, int y, int width, int height, int startAngle, int spanAngle)

В метод передается прямоугольная область, на основе которой формируется овал. А последние два параметра определяют начальный и конечный угол, которые применяются для обрезки дуги. Последние два параметра должны быть указаны в 1/16 градуса, т. е. полный круг равен 5760 (16 * 360). Положительные значения углов означают направление против часовой стрелки, а отрицательные значения означают направление по часовой стрелке. Пример дуги:

class MyWidget : public QWidget
{
    void paintEvent(QPaintEvent *)
    {
        QRectF rectangle(10.0, 20.0, 180.0, 160.0);
        int startAngle = 30 * 16;
        int spanAngle = 120 * 16;

        QPainter painter(this);
        painter.drawArc(rectangle, startAngle, spanAngle);
    }
};
Отрисовка дуг и метод drawArc в виджетах Qt

Отрисовка кругового сектора

Для открисовки кругового сектора применяется метод drawPie():

void drawPie(const QRectF &rectangle, int startAngle, int spanAngle)
void drawPie(int x, int y, int width, int height, int startAngle, int spanAngle)
void drawPie(const QRect &rectangle, int startAngle, int spanAngle)

В метод передаются параметры прямоугольной области для построения окружности и начальный и конечный углы, которые применяются для обрезки сектора. Применение

class MyWidget : public QWidget
{
    void paintEvent(QPaintEvent *)
    {
        QRectF rectangle(10.0, 20.0, 180.0, 160.0);
        int startAngle = 30 * 16;
        int spanAngle = 120 * 16;

        QPainter painter(this);
        painter.drawPie(rectangle, startAngle, spanAngle);
    }
};
Отрисовка кругового сектора и метод drawPie в виджетах Qt

Отрисовка пути

Для отрисовки пути QPainter предоставляет метод drawPath(), в который передается ссылка на объект QPainterPath:

drawPath(const QPainterPath &path)

Тип QPainterPath представляет геометрический путь, который объединяет простейшие графические примитивы. Для добавления примитивов в путь класс предоставляет ряд методов. Основные из них:

  • addEllipse(): добавляет эллипс

  • addPath(): добавляет другой путь

  • addPolygon(): добавляет многоугольник

  • addRect(): добавляет прямоугольник

  • addRoundedRect(): добавляет прямоугольник с загругленными углами

  • addText(): добавляет текст

  • arcTo(): добавляет дугу

  • cubicTo(): добавляет кубическую кривую Безье

  • lineTo(): добавляет линию

  • quadTo(): добавляет квадратную кривую Безье

Посмотрим на простейшем примере с добавлением линий:

#include <QApplication>
#include <QWidget>
#include <QPainter>
#include <QPainterPath>

class MyWidget : public QWidget
{
    void paintEvent(QPaintEvent *event)
    {
        QPainterPath path;
        path.moveTo(115, 10);
        path.lineTo(230, 140);
        path.lineTo(10, 140);
        path.lineTo(115, 10);

        QPainter painter(this);
        painter.drawPath(path);
    }
};

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    MyWidget widget;
    widget.setFixedSize(250, 150);
    widget.setWindowTitle("METANIT.COM");

    widget.show();
    return app.exec();
}

В данном случае в путь добавляются три линии, которые в целом образуют треугольник

Отрисовка геометрического пути с QPainter в Qt и C++

В примере выше в путь добавляются три линии, но в реальности нам достаточно двух линий, поскольку класс QPainterPath предоставляет метод closeSubpath(), который позволяет закрыть путь - автоматически соединить линией первую и последнюю точку пути:

class MyWidget : public QWidget
{
    void paintEvent(QPaintEvent *event)
    {
        QPainterPath path;
        path.moveTo(115, 10);
        path.lineTo(230, 140);
        path.lineTo(10, 140);
        //path.lineTo(115, 10);
        path.closeSubpath();    // закрываем путь

        QPainter painter(this);
        painter.drawPath(path);
    }
};
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850