QPainter, рисование текста без заливки

180
12 июля 2018, 00:40

Как написать такой текст с помощью QPainter, чтобы текст изнутри был прозрачным?

Answer 1

Сам QPainter не поддерживает непосредственное рисование контура текста. Однако вы можете создать этот контур отдельно, с помощью QPainterPath::addText().

То есть для получения текста без заливки надо:

  1. Векторизовать его:

    QPainterPath outline_text;
    outline_text.addText(положение, шрифт, текст);
    
  2. И затем отрисовать:

    QPainter painter(this);
    painter.strokePath(outline_text, перо);
    

Вот минимальный демонстрационный пример:

#include <QApplication>
#include <QBrush>
#include <QFont>
#include <QPalette>
#include <QPen>
#include <QPainter>
#include <QPaintEvent>
#include <QPainterPath>
#include <QWidget>
/* ************* */
class Canvas : public QWidget {
public:
    Canvas();
protected:
    void paintEvent(QPaintEvent *event);
private:
    QPainterPath outline_text;
    QPen outline_pen;
    QRect outline_bounds;
};
/* ************* */
Canvas::Canvas()
    : outline_pen(Qt::lightGray, 2)
{
    // "Запекаем" контур надписи в экземпляр QPainterPath. И да, текст мы размещаем
    // в начале координат, так как всё равно потом будем динамически перемещать его
    // в центр окна
    QFont outline_font(QLatin1String("serif"), 64);
    outline_text.addText(QPoint(), outline_font, QLatin1String("Hello, World"));
    // Сохраняем описывающий прямоугольник для дальнейшего центрирования надписи
    outline_bounds = outline_text.controlPointRect().toRect();
    // Устанавливаем белый цвет фона
    QPalette pal(palette());
    pal.setColor(QPalette::Background, Qt::white);
    setPalette(pal);
}
void Canvas::paintEvent(QPaintEvent *event)
{
    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing);
    // Перемещаем надпись в центр окна
    const QPoint outline_center = outline_bounds.center();
    const QPoint canvas_center = rect().center();
    painter.translate(canvas_center - outline_center);
    // Рисуем контур
    painter.strokePath(outline_text, outline_pen);
    event->accept();
}
/* ************* */
int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    Canvas canvas;
    canvas.show();
    return app.exec();
}

И результат его работы:

    

READ ALSO
Ошибка сегментирования (С++)

Ошибка сегментирования (С++)

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

154
Visual Studio и Makefile

Visual Studio и Makefile

Надо было тестово собрать один проект под VS для проверки совместимости кода, в общем все собирается, но выдает следующее:

146
Проблема с выводом c++ (sort, copy)

Проблема с выводом c++ (sort, copy)

Проблема с copyВ "Task 1" все работает, но в "Task 2" после выполнения sort выводит только название группы и ссылается на

162
Spring Failed to start component

Spring Failed to start component

Начал изучать спринг, создал с помощью инициализатора проект и ввёл в него код-пример с этого сайтаВ итоге в проекте есть один класс:

247