Три Qt 2D рисования: рисовать текст, путь, изображения, многомодовый

Во-первых, нарисовать текст

Помимо рисования графика, вы можете также использовать функцию QPainter :: darwText () для рисования текста, вы можете также использовать QPainter :: SetFont () , чтобы установить шрифт , используемый в тексте, используя функцию QPainter :: FontInfo () , чтобы получить информацию о шрифтах, его вернуть QFontInfo объект класса. При составлении текста используется антиалиасинг по умолчанию.


1.1 Основные Drawing

Следующий код показывает содержимое программы были все еще на одном, изменить paintEvent () выглядит следующим образом:

void Widget::paintEvent(QPaintEvent *)
{    
      QPainter painter(this);    
      painter.drawText(100, 100,  "qter.org-yafeilinux");
}

Таким образом, положение (100, 100) рисует строку. Результаты, как показано на фиг.

01.png


1.2 управления положением текста

Мы первая страница QPainter документация помощи, а затем просмотреть DrawText () функция перегрузки, найдено:

QPainter::drawText ( const QRectF & rectangle, int flags, const QString & text, QRectF * boundingRect = 0 )
  • Первый параметр определяет прямоугольник, в котором текст нарисованный;
  • Второй параметр определяет выравнивание текста в виде прямоугольника, который определяется перечислимого типа Qt :: AlignmentFlag, другой расклад может быть «|» является оператором одновременно, может быть использовано в данном описании , как определено Qt :: TextFlag другие признаки, такие как перенос слов и так далее;
  • Третий параметр является текстом, который можно сделать, где вы можете использовать «\ N» для достижения обертки;
  • Четвертый параметр обычно не устанавливается.


Давайте посмотрим на пример. Для того, чтобы более четко видеть положение текста в заданном прямоугольнике, мы рисуем прямоугольник. Функция paintEvent () изменяется следующим образом:

void Widget::paintEvent(QPaintEvent *)
{
    QPainter painter(this);
    //设置一个矩形
    QRectF rect(50, 50, 300, 200);
    //为了更直观地看到字体的位置,我们绘制出这个矩形
    painter.drawRect(rect);
    painter.setPen(QColor(Qt::red));
    //这里先让字体水平居中
    painter.drawText(rect, Qt::AlignHCenter, "yafeilinux");
}

Теперь запустите программу, результаты, как показано на фиг.

03.png


Доступен как выравнивание, показанного на фиг.

04.png


1.3 Использование шрифтов

Чтобы нарисовать красивый текст, вы можете использовать класс QFont установить шрифт текста. Вы можете также видеть введение в классе в справочной документации. Наиболее часто используемые настройки ниже демонстрируют.

Функция paintEvent () изменяется следующим образом:

void Widget::paintEvent(QPaintEvent *)
{
    QPainter painter(this);
    //设置一个矩形
    QRectF rect(50, 50, 300, 200);
    //为了更直观地看到字体的位置,我们绘制出这个矩形
    painter.drawRect(rect);
    painter.setPen(QColor(Qt::red));
    //这里先让字体水平居中
    painter.drawText(rect, Qt::AlignHCenter, "yafeilinux");

    //使用字体
    QFont font("宋体", 15, QFont::Bold, true);
    //设置下划线
    font.setUnderline(true);
    //设置上划线
    font.setOverline(true);
    //设置字母大小写
    font.setCapitalization(QFont::SmallCaps);
    //设置字符间的间距
    font.setLetterSpacing(QFont::AbsoluteSpacing, 10);
    //使用字体
    painter.setFont(font);
    painter.setPen(Qt::blue);
    painter.drawText(120, 80, tr("yafeilinux"));
    painter.translate(50, 50);
    painter.rotate(90);
    painter.drawText(0, 0, tr("helloqt"));
}

这里创建了QFont字体对象,使用的构造函数为QFont::QFont ( const QString & family,int pointSize = -1, int weight = -1, bool italic = false ),第一个参数设置字体的family属性,这里使用的字体族为宋体,可以使用QFontDatabase类来获取所支持的所有字体;第二个参数是点大小,默认大小为12;第三个参数为weight属性,这里使用了粗体;最后一个属性设置是否使用斜体。然后我们又使用了其他几个函数来设置字体的格式,最后调用setFont()函数来使用该字体,并使用drawText()函数的另一种重载形式在点(120, 80)绘制了文字。后面又将坐标系统平移并旋转,然后再次绘制了文字。运行程序,效果如下图所示。

05.png



二、绘制路径

如果要绘制一个复杂的图形,那么可以使用QPainterPath类,然后使用QPainter::drawPath()来进行绘制。QPainterPath类为绘制操作提供了一个容器,可以用来创建图形并且重复使用。一个绘图路径就是由多个矩形、椭圆、线条或者曲线等组成的对象,一个路径可以是封闭的,例如矩形和椭圆;也可以是非封闭的,例如线条和曲线。


2.1 简单应用

下面看一个例子:添加一个椭圆和一根线在图形路径里。依然在前面的项目中进行讲解。更改paintEvent()函数如下:

void Widget::paintEvent(QPaintEvent *)
{
    //添加一个椭圆和一根线在图形路径里
    QPainterPath path;
    path.addEllipse(100, 100, 50, 50); //添加一个圆心为(100,100),横纵半径都为50的椭圆
    path.lineTo(200, 200); //添加一根从当前位置到(200,200)的线
    QPainter painter(this);
    painter.setPen(Qt::blue);
    painter.setBrush(Qt::red);
    painter.drawPath(path);
}

当创建一个QPainterPath对象后,可以使用lineTo()、arcTo()、cubicTo()和quadTo()等函数将直线或者曲线添加到路径中。运行程序,效果如下图所示。

01.png


2.2 复制图形

如果只是简单的将几个图形拼接在一起,其实完全没有必要用路径,之所以要引入路径,就是因为它的一个非常有用的功能:复制图形路径。更改paintEvent()函数如下:

void Widget::paintEvent(QPaintEvent *)
{
    //添加一个椭圆和一根线在路径里
    QPainterPath path;
    path.addEllipse(100, 100, 50, 50); //添加一个圆心为(100,100),横纵半径都为50的椭圆
    path.lineTo(200, 200); //添加一根从当前位置到(200,200)的线
    QPainter painter(this);
    painter.setPen(Qt::blue);
    painter.setBrush(Qt::red);
    painter.drawPath(path);

    //复制图形路径
    QPainterPath path2;
    path2.addPath(path);
    path2.translate(100,0);
    painter.drawPath(path2);
}

现在运行程序,效果如下图所示。

02.png

可以看到,对于已经绘制好的路径,可以非常简单地进行重复绘制。


2.3 绘制图形时的当前位置

我们先来看一个例子,将paintEvent()函数更改如下:

void Widget::paintEvent(QPaintEvent *)
{
    QPainterPath path;
    path.lineTo(100, 100);
    path.lineTo(200, 100);
    QPainter painter(this);
    painter.drawPath(path);
}

程序运行效果如下图所示。

03.png

可以看到,创建路径后,默认是从(0, 0)点开始绘制的,当绘制完第一条直线后当前位置是(100, 100)点,从这里开始绘制第二条直线。绘制完第二条直线后,当前位置是(200, 100)。


我们也可以使用moveTo()函数来改变当前点的位置。例如将paintEvent()函数更改如下:

void Widget::paintEvent(QPaintEvent *)
{
    QPainterPath path;
    path.addRect(50, 50, 40, 40);

    //移动到(100, 100)点
    path.moveTo(100, 100);

    path.lineTo(200, 200);
    QPainter painter(this);
    painter.drawPath(path);
}

这样当绘制完矩形以后,就会移动到(100, 100)点进行后面的绘制。程序运行效果如下图所示

05.png



三、绘制图片

Qt提供了四个类来处理图像数据:QImage、QPixmap、QBitmap和QPicture,它们都是常用的绘图设备。其中QImage主要用来进行I/O处理,它对I/O处理操作进行了优化,而且可以用来直接访问和操作像素;QPixmap主要用来在屏幕上显示图像,它对在屏幕上显示图像进行了优化;QBitmap是QPixmap的子类,用来处理颜色深度为1的图像,即只能显示黑白两种颜色;QPicture用来记录并重演QPainter命令。这一节我们只讲解QPixmap。


3.1 简单绘制图片

(1)这次我们重新创建一个Qt Widgets应用,项目名称为mypixmap,在类信息页面,将基类选择为QDialog,类名使用默认的Dialog即可。


(2)然后在源码目录中复制一张图片,比如这里是一张logo.png图片,如下图所示。

01.png


(3)在dialog.h文件中添加重绘事件处理函数的声明:

protected:
    void paintEvent(QPaintEvent *);


(4)到dialog.cpp文件中先添加头文件包含#include <QPainter>,然后添加函数的定义:

void Widget::paintEvent(QPaintEvent *)
{
    QPainter painter(this);
    QPixmap pix;
    pix.load("../mypixmap/logo.png");
    painter.drawPixmap(0, 0, 80, 100, pix);
}

这里使用了相对路径,因为Qt Creator默认是使用影子构建,即编译生成的文件在build-mypixmap-Desktop_Qt_5_8_0_MinGW_32bit-Debug这样的目录里面,而这个目录就是当前目录,所以源码目录就是其上级目录了。大家可以根据自己的实际情况来更改路径,也可以使用绝对路径,不过最好使用资源文件来存放图片。drawPixmap()函数在给定的矩形中来绘制图片,这里矩形的左上角顶点为(0, 0)点,宽80,高100,如果宽高跟图片的大小比例不同,默认会拉伸图片。运行效果如下图所示。

02.png


3.2 平移图片

QPainter类中的translate()函数实现坐标原点的改变,改变原点后,此点将会成为新的原点(0,0)。下面来看一个例子。在paintEvent()函数中继续添加如下代码:

//将(100,100)设为坐标原点
painter.translate(100, 100);
painter.drawPixmap(0, 0, 80, 100, pix);

这里将(100,100)设置为了新的坐标原点,所以下面在(0,0)点贴图,就相当于在以前的(100,100)点贴图。运行程序,效果如下图所示。

03.png


3.3 缩放图片

我们可以使用QPixmap类中的scaled()函数来实现图片的放大和缩小。在paintEvent()函数中继续添加如下代码:

//获得以前图片的宽和高
qreal width = pix.width();
qreal height = pix.height();
//将图片的宽和高都缩小,并且在给定的矩形内保持宽高的比值不变
pix = pix.scaled(width, height,Qt::KeepAspectRatio);
painter.drawPixmap(90, 90, pix);

其中参数Qt::KeepAspectRatio,是图片缩放的方式。可以将鼠标指针放到该代码上,按下F1键查看其帮助了,如下图所示。

04.png

这里有三个值,只看其示例图片就可大致明白,Qt::IgnoreAspectRatio是不保持图片的宽高比;Qt::KeepAspectRatio是在给定的矩形中保持宽高比;最后一个也是保持宽高比,但可能超出给定的矩形。这里给定的矩形是由我们显示图片时给定的参数决定的,例如painter.drawPixmap(0,0,100,100,pix);就是在以(0,0)点为起始点的宽和高都是100的矩形中。运行程序效果如下图所示。

05.png


3.4 旋转图片

旋转使用的是QPainter类的rotate()函数,它默认是以原点为中心进行旋转的。如果要改变旋转的中心,可以使用前面讲到的translate()函数完成。在paintEvent()函数中继续添加如下代码:

//让图片的中心作为旋转的中心
painter.translate(40, 50);
painter.rotate(90); //顺时针旋转90度
painter.translate(-40,-50); //使原点复原
painter.drawPixmap(100, 100, 80, 100, pix);

这里必须先改变旋转中心,然后再旋转,然后再将原点复原,才能达到想要的效果。运行程序,如下图所示。

06.png


3.5 扭曲图片

实现图片的扭曲,是使用的QPainter类的shear(qreal sh,qreal sv)函数完成的。它有两个参数,前面的参数实现横向变形,后面的参数实现纵向变形。当它们的值为0时,表示不扭曲。在paintEvent()中继续添加如下代码:

painter.shear(0.5, 0); //横向扭曲
painter.drawPixmap(100, 0, 80, 100, pix);

运行效果如下图所示。

07.png



四、复合模式

QPainter обеспечивает композитный рисунок (Режимы композиции) , чтобы определить , как для завершения составного цифрового изображения, то есть, как целевое изображение , и пиксели исходного изображения объединяются. Общий режим и композитный эффект при условии , QPainter показано ниже. Один общий типа SoiirceOver (обычно упоминается как альфа - смешивание), исходные пиксели будучи нарисованным смешивают на целевой пикселе было составлено, исходный пиксель альфа - компонент определяет его прозрачность, таким образом , что исходное изображение будет прозрачный эффект отображается на целевом изображении. Когда несколько режимов установлены, он будет применяться ко всем операциям рисования, такие как ручки, кисть и градиент пиксельной карты / рисование изображения и тому подобные.

IMG


Пример:

void Widget::paintEvent(QPaintEvent *event)
{
    QPainter painter;
    QImage image(400, 300, QImage::Format_ARGB32_Premultiplied);
    painter.begin(&image);
    painter.setBrush(Qt::green);
    painter.drawRect(100, 50, 200, 200);
    painter.setBrush(QColor(0, 0, 255, 150));
    painter.drawRect(50, 0, 100, 100);
    painter.setCompositionMode(QPainter::CompositionMode_SourceIn);
    painter.drawRect(250, 0, 100, 100);
    painter.setCompositionMode(QPainter::CompositionMode_DestinationOver);
    painter.drawRect(50, 200, 100, 100);
    painter.setCompositionMode(QPainter::CompositionMode_Xor);
    painter.drawRect(250, 200, 100, 100);
    painter.end();
    painter.begin(this);
    painter.drawImage(0, 0, image);
}

Здесь Qlmage первого рисовать на прямоугольнике, а затем в четырех углов прямоугольника рисуются четыре маленьких прямоугольников, каждый маленький прямоугольник использует различные модели композитных и используется для заполнения полупрозрачные цветов. Первый небольшой прямоугольный режим комплекса явно не указан, то по умолчанию использует режим SourceOver. Эффект операции , как показано на фиг.

IMG



Ссылка:

Первые 13 Qt5 2D чертеж (с) рисования текста

Глава 14 2D рисунок Qt5 (d) путь рисования

66 2D чертеж (рисунок текста, путь, режим изображения)


рекомендация

отwww.cnblogs.com/linuxAndMcu/p/11059635.html