天天看点

学习QT之QT绘图原理详解

一、Qt绘制事件

当应用程序收到绘制事件时,就会调用​

​QWidget::paintEvent()​

​,该函数就是绘制窗口的地方。

有两种方法要求重绘一个窗口

  1. ​update()​

    ​ --把重绘事件添加到事件队列中
  • 重复调用​

    ​update()​

    ​会被Qt合并为一次
  • 不会产生图像的闪烁
  • 可带参数指定重绘某个区域
  1. ​repaint()​

    ​ --立即产生绘制事件
  • 一般情况下不推荐使用此方法
  • 只使用在需要立即重绘的特效情况下
  • 可带参数指定重绘某个区域

为了处理绘制事件,只需要重写​

​paintEvent()​

​​函数,并在该函数中实例化一个​

​QPainter​

​对象进行绘制。

class MyWidget : public QWidget
{
    ...
protected:
    void paintEvent(QPaintEvent *);
}

void MyWidget::paintEvent(QPaintEvent *event)
{
    QPainter painter(this);
    ...
}      
学习QT之QT绘图原理详解

基本绘制

  • ​QPainter​

    ​类提供绘制操作,其构造函数原型为:
QPainter(QPaintDevice *device);      
  • ​QPaintDevice​

    ​代表绘制2D图像的画布;
  • 如下继承​

    ​QPaintDevice​

    ​的类对象都可用于​

    ​QPainter​

    ​绘制
QWidget、QImage、QPixmap、QPicture、QPrinter、QSvgGenerator、
QGLPixelBuffer、QGLFrameBufferObject      

二、Qt 2D绘图

QPainter

  1. 线和轮廓都可以用画笔(QPen)进行绘制,用画刷(QBrush)进行填充;
  2. 字体使用​

    ​QFont​

    ​类定义,当绘制文字时,Qt使用指定字体的属性,如果没有匹配的字体,Qt将使用最接近的字体;
  3. 通常情况下,​

    ​QPainter​

    ​​以默认的坐标系统进行绘制,也可以用​

    ​QMatrix​

    ​类对坐标进行变换;
  4. 当绘制是,可以使用​

    ​QPainter::RenderHint​

    ​来告诉绘图引擎是否弃用反锯齿功能使图变得平滑;
  5. ​QPainter::RenderHint​

    ​的可取值:
  • ​QPainter::Antialiasing​

    ​:告诉绘图引擎应该在可能的情况下进行边的反锯齿绘制
  • ​QPainter::TextAntialiasing​

    ​:尽可能的情况下文字的反锯齿绘制
  • ​QPainter::SmoothPixmapTransform​

    ​:使用平滑的pixmap变换算法(双线性插值算法),而不是近邻插值算法;

QPainter的绘图函数总结如下:

函数 功能 函数 功能
drawArc() drawPixmap() QPixmap表示的图像
drawChord() drawPoint()
drawConvexPolygon() 凸多边形 drawPoints() 多个点
drawEllipse() 椭圆 drawPolygon 多边形
drawImage() QImage表示的图像 drawPolyline() 多折线
drawLine() 线 drawRect() 矩形
drawLines() 多条线 drawRects() 多个矩形
drawPath() 路径 drawRoundRect() 圆角矩形
drawPicture() 按QPainter指令绘制 drawText() 文字
drawPie 扇形 drawTiledPixmap() 平铺图像
drawLineSegments() 绘制折线

三、画笔

  • 画笔的属性包括线型、线宽、颜色等。画笔属性可以在构造函数中指定,也可以使用​

    ​setStyle()​

    ​​,​

    ​setWidth()​

    ​​,​

    ​setBrush()​

    ​​,​

    ​setCapStyle()​

    ​​,​

    ​setJoinStyle()​

    ​等函数设定;
  • Qt中,使用Qt::PenStyle定义了6中画笔风格,分别是:
学习QT之QT绘图原理详解

​ 还可以自定义线风格(​

​Qt::CustomDashLine​

​​),需要使用QPen的​

​setDashPattern()​

​函数来设定自定义风格。

端点风格(cap style)

  • 端点风格决定了线的端点样式,只对线宽大于1的线有效。
  • Qt定义了三种端点风格用枚举类型​

    ​Qt::PenCapStyle​

    ​表示,分别为:
学习QT之QT绘图原理详解

​Qt::PenCapStyle​

说明
Qt::SquareCap 表示在线条的顶点处是方形的,且线条绘制的区域包括了端点,并且再往外延伸半个线宽的长度
Qt::FlatCap 表示在线条的顶点处是方形的,但线条绘制区域不包括端点在内
Qt::RoundCap 表示在线条的顶点处是圆形的,且线条绘制区域包含了端点。

连接风格(join style)

  • 连接风格是两条线如何连接,连接风格对线宽大于等于1的线有效;
  • Qt定义了四种连接方式,用枚举类型​

    ​Qt::PenStyle​

    ​表示。分别是:
  • 学习QT之QT绘图原理详解

​Qt::PenStyle​

说明
Qt::BevelJoin 指两条线的中心线顶点相汇,相连处依然保留线条各自的方形顶端
Qt::MiterJoin 指两条线的中心线顶点相汇,相连处线条延长到线的外侧汇集至点,形成一个尖顶的连接
Qt::RoundJoin 指两条线的中心线顶点相汇,相连处以圆弧形连接

四、画刷

  1. 在Qt中图形使用​

    ​QBrush​

    ​进行填充,画刷包括填充颜色和风格(填充模式)。
  2. 在Qt中,颜色使用​

    ​QColor​

    ​​类表示,​

    ​QColor​

    ​支持RGB、HSV、CMYK颜色模型。QColor还支持alpha混合的轮廓和填充。
  • RGB是面向硬件的模型。颜色有红绿蓝三种基色混合而成。
  • HSV/HSL模型比较符合人对颜色的感觉,由色调(0-359),饱和度(0-255),亮度(0-255)组成,主要用于颜色选择器。
  • CMYK由青、洋红、黄、黑四种基色组成。主要用于打印机等硬件拷贝设备上。每个颜色分量的取值是0-255。
  1. 基本模式填充包括有各种点、线组合的模式。

QColor

​QColor​

​​的构造函数:​

​QColor(int r,int g,int b,int a)​

其中 参数a(alpha)是控制透明度的,取值范围为0-255;0为完全透明,255为不透明。

颜色还可以使用如下函数进行微调

QColor::lighter(int factor)
QColor::darker(int factor)      

QRgb

  • QRgb类可以用于保存颜色值,可与QColor相互转换获取32-bit的RGB颜色值+alpha值。
  • 创建新颜色
QRgb orange = qRgb(255,127,0);
QRgb overlay = qRgb(255,0,0,100);      
  • 获取单独某个颜色值:qRed,qGreen,qBlue,qAlpha
int red = qRed(orange);      
  • 获取灰度值
int gray = qGray(orange);      

模式画刷

模式化画刷构造函数​

​QBrush(const QColor *color,Qt::BrushStyle style)​

​,具体见下图:

五、渐变填充

  • Qt提供了渐变填充的画刷,渐变填充包括两个要素:颜色的变化和路径的变化
  • 颜色变化可以指定从一种颜色渐变到另外一种颜色。
  • 路径变化指在路径上指定一些点的颜色进行分段渐变。
  • Qt中,提供了三种渐变填充
  • 线性(QLinearGradient)
  • 圆形(QRadialGradient)
  • 圆锥渐变(QConicalGradient)
  • 所有的类都从QGradient类继承
  • 构造渐变填充的画刷
QBrush b = QBrush(QRadialGradient(...));      
  • 从图形的起点到终点,以从0至1的比例渐变填充
QGradient::setColorAt(qreal pos,QColor color);      
  • 完成0-1范围的填充后,后续颜色铺开的方式可以不同,通过​

    ​setSpread()​

    ​函数来设置

1、线性渐变填充

  • 线性渐变填充指定两个控制点,画刷在两个控制点之间进行颜色插值。
  • 通过创建​

    ​QLinearGradient​

    ​对象来设置画刷。
QPainter painter(this);
QLinearGradient g(0,0,100,100);
g.setColorAt(0.0,Qt::white);
g.setColorAt(1.0,Qt::blue);
painter.setBrush(g);
p.drawRect(0,0,100,100);      
  • 在​

    ​QGradient​

    ​构造函数中指定线性填充的两点分别为(0,0),(100,100)。
  • ​setColorAt()​

    ​函数在0-1之间设置指定位置的颜色。

2、圆形渐变填充

  • 圆形渐变填充需要指定圆心、半径和焦点
QRadialGradient(qreal cx,qreal cy,qreal radius,qreal fx,qreal fy);      
  • 画刷在焦点和圆上的所有点之间进行颜色插值。
  • 创建​

    ​QRadialGradient​

    ​对象设置画刷
QPainter painter(this);
QRadialGradient radialGradient(50,50,50,30,30);
radialGradient.setColorAt(0.0,Qt::white);
radialGradient.setColorAt(1.0,Qt::blue);
painter.setBrush(radialGradient);
painter.drawRect(0,0,100,100);      

3、圆锥渐变填充

  • 圆锥渐变填充指定圆形和开始角
QConicalGradient(qreal cx,qreal cy,qreal angle);      
  • 画刷沿圆心逆时针对颜色进行插值
  • 创建​

    ​QConicalGradient​

    ​对象并设置画刷
QPainter painter(this);
QConicalGradient conicalGradient(50,50,90);
conicalGradient.setColorAt(0,Qt::white);
conicalGradient.setColorAt(1,Qt::blue);
painter.setBrush(conicalGradient);
painter.drawRect(0,0,100,100);      
  • 为了实现自定义填充,还可以使用QPixmap或者QImage对象进行纹理填充。两种图像分别使用​

    ​setTexture()​

    ​和​

    ​setTextureImage()​

    ​函数加载纹理。

继续阅读