세 Qt는 2D 도면 : 텍스트, 경로, 이미지, 멀티 모드를 그릴

첫째, 텍스트를 그릴

그래프를 그리는 것 외에, 또한 텍스트를 그리기 QPainter를 :: darwText () 함수를 사용할 수 있고, 또한 폰트 정보를 얻을 QPainter를 :: 된 FontInfo () 함수를 사용하여, 본문에 사용 된 폰트를 설정할 QPainter를 ::의 setFont ()를 사용하여 그것을 QFontInfo 클래스 오브젝트를 돌려줍니다. 텍스트를 그리기 앤티 앨리어싱 기본값을 사용하는 경우.


1.1 기본 그리기

다음 코드는) 프로그램의 내용이 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


도 1에 도시 된 배향으로 제공.

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가 제공된 합성 효과. 소스 이미지는 투명 효과 될 수 있도록 하나 개의 일반적인 유형이 그려지는 소스 픽셀이 그려져 대상 화소에 혼합 (일반적으로 알파 블렌딩 (alpha blending)으로 지칭) 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 직사각형 무승부 후 사각형의 네 모서리의 4 개 개의 작은 사각형을 그려, 각각의 작은 사각형은 다른 복합 패턴을 사용하고, 반투명 색을 채우기 위해 사용된다. 제 작은 사각형 복합 모드는 명시 SourceOver 모드를 사용하여 그것을 디폴트를 지정하지 않는다. 도에 나타내는 바와 같이 조작 효과.

IMG



참조 :

텍스트 드로잉 드로잉 제 13 Qt5 2D (c)

Qt5 (d) 드로잉 경로를 드로잉 (2d)의 제 14

66 차원 도면 (도면 텍스트, 경로, 화상 모드)


추천

출처www.cnblogs.com/linuxAndMcu/p/11059635.html