Как рисовать пользовательские фигуры (например, слезы) в Qt с помощью QPainter или QPainterPath, используя одну фигуру или объединенную группу фигур

у меня есть этот простой вопрос, я не могу нарисовать фигуру, как слеза, но без использования более одной фигуры (эллипс и многоугольник), потому что QPen является рисовать для каждой фигуры, я хочу что-то вроде соединения форм для создания новый, или скажите QT, что вокруг границы между обеими фигурами, для получения дополнительной информации о том, что я хочу увидеть изображение, я хочу создать такой шейб: https://docs.google.com/open?id=0Bxb0hT_U-KqJSHZUMTF2eFlOYzg

Скажите, можете ли вы увидеть изображение и понять, чего я хочу, и спасибо за вашу помощь.

7

Решение

Если фигура, которую вы хотите нарисовать, может быть представлена ​​в виде слоев других фигур, как с изображением, к которому вы привязали, это довольно легко сделать:

Сначала нам нужно построить QPainterPath представлять внешний край фигуры. Мы строим это путем наложения простых форм; в случае вашего примера нам нужны круг и квадрат. Обратите внимание на использование QPainterPath::setFillRule(Qt::WindingFill): это позже повлияет на способ рисования пути (попробуйте удалить его, чтобы увидеть разницу!).

QPainterPath OuterPath;
OuterPath.setFillRule(Qt::WindingFill);
OuterPath.addEllipse(QPointF(60, 60), 50, 50);
OuterPath.addRect(60, 10, 50, 50);

В приведенном вами примере нам также нужно удалить круглую область от центра нашей заполненной фигуры. Давайте представим эту внутреннюю «границу» как QPainterPath а затем использовать QPainterPath::subtracted() вычесть InnerPath от OuterPath и производим нашу окончательную форму:

QPainterPath InnerPath;
InnerPath.addEllipse(QPointF(60, 60), 20, 20);

QPainterPath FillPath = OuterPath.subtracted(InnerPath);

После того как мы построили контуры формы, нам нужно использовать их, чтобы заполнить / очертить форму. Давайте сначала создадим QPainter и установите его для использования сглаживания:

QPainter Painter(this);
Painter.setRenderHint(QPainter::Antialiasing);

Затем нам нужно заполнить форму, которую мы построили:

Painter.fillPath(FillPath, Qt::blue);

Наконец, давайте нарисуем контуры. Обратите внимание, что, поскольку у нас есть отдельные пути для внутренних и внешних границ, мы можем обводить каждую границу разными толщинами линий. Обратите внимание также на использование QPainterPath::simplified(): это преобразует набор слоистых фигур в одну QPainterPath который не имеет пересечений:

Painter.strokePath(OuterPath.simplified(), QPen(Qt::black, 1));
Painter.strokePath(InnerPath, QPen(Qt::black, 3));

Если мы соберем все это вместе, это будет выглядеть так:

void Shape::paintEvent(QPaintEvent *)
{
QPainterPath OuterPath;
OuterPath.setFillRule(Qt::WindingFill);
OuterPath.addEllipse(QPointF(60, 60), 50, 50);
OuterPath.addRect(60, 10, 50, 50);

QPainterPath InnerPath;
InnerPath.addEllipse(QPointF(60, 60), 20, 20);

QPainterPath FillPath = OuterPath.subtracted(InnerPath);

QPainter Painter(this);
Painter.setRenderHint(QPainter::Antialiasing);

Painter.fillPath(FillPath, Qt::blue);
Painter.strokePath(OuterPath.simplified(), QPen(Qt::black, 1));
Painter.strokePath(InnerPath, QPen(Qt::black, 3));
}
17

Другие решения

Это на самом деле довольно сложно сделать без хорошего математического фона. Если бы вы знали формулу для создания этой формы, вы могли бы просто поместить ее в свой QGraphicsItem::paint() функция. Но есть несколько альтернатив:

  1. Сделайте изображение в векторной программе редактирования, такой как Inkscape (бесплатно), сохраните его как файл .svg, а затем загрузите его в QGraphicsSvgItem. (Это то, что я бы сделал.)

  2. Посмотри на QPainterPath :: cubicTo (), который позволяет сделать кривую Безье

2

По вопросам рекламы [email protected]