Как рисовать пользовательские фигуры (например, слезу) в Qt с помощью QPainter или QPainterPath, используя одну фигуру или группу фигур
У меня есть этот простой вопрос, я не могу нарисовать фигуру, как слеза, но без использования более одной фигуры (эллипс и многоугольник), потому что QPen рисует для каждой фигуры, я хочу что-то вроде объединения фигур для создания новой или сказать QT, что вокруг границы между обеими фигурами, для получения дополнительной информации о том, что я хочу видеть изображение, я хочу создать шабе:https://docs.google.com/open?id=0Bxb0hT_U-KqJSHZUMTF2eFlOYzg
скажите мне, если вы можете увидеть изображение и понять, что я хочу, и спасибо за вашу помощь.
2 ответов
если фигура, которую вы хотите нарисовать, может быть представлена в виде слоев других фигур, как с изображением, с которым вы связаны, это довольно легко сделать:
Сначала нам нужно построить 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));
}
это на самом деле довольно сложно сделать без хорошего математического фона. Если бы вы знали формулу для создания этой формы, вы могли бы просто поместить ее в свой . Но есть несколько альтернатив:
сделать изображение в программе векторного редактирования, как Inkscape (бесплатно), сохранить его как.svg-файл, а затем загрузите его в QGraphicsSvgItem. (Вот что бы я сделал.)
посмотреть QPainterPath::cubicTo(), что позволяет сделать кривую Безье