界面优化 - 绘图

彩虹网

目录

1. 基本概念

虽然 Qt 已经内置了很多的控件, 但是不能保证现有控件就可以应对所有场景.

很多时候我们需要更强的 "自定制" 能力.

Qt 提供了画图相关的 API, 可以允许我们在窗上绘制任意的图形形状, 来完成更复杂的界面设计.

绘图 API 核心类:

说明

QPainter

"绘画者" 或者 "画家". 用来绘图的对象, 提供了⼀系列 drawXXX 方法, 可以允许我们绘制各种图形.

QPaintDevice

"画板". 描述了 QPainter 把图形画到哪个对象上. 像我们之前用过的 QWidget 也是⼀种 QPaintDevice (QWidget 是 QPaintDevice 的子类) .

QPen

"画笔". 描述了 QPainter 画出来的线是什么样的.

QBrush

"画刷". 描述了 QPainter 填充一个区域是什么样的.

绘图 API 的使用, 一般不会在 QWidget 的构造函数中使用, 而是要放到 paintEvent 事件中.

关于 paintEvent

paintEvent 会在以下情况下被触发:

因此, 如果把绘图 api 放到构造函数中调用, 那么一旦出现上述的情况, 界面的绘制效果就无法确保符合预期了.

2. 绘制各种形状 2.1 绘制线段

void drawLine(const QPoint &p1, const QPoint &p2);

参数:

void drawLine ( int x1, int y1, int x2, int y2 );

参数:

示例:

1、在 "widget.h" 头文件中声明绘图事件;

class Widget : public QWidget
{
    Q_OBJECT
public:
    Widget(QWidget *parent = nullptr);
    ~Widget();
    
    // 声明绘图事件
    void paintEvent(QPaintEvent *event);
private:
    Ui::Widget *ui;
};

2、在 "widget.cpp" 文件中重写 paintEvent() 方法;

void Widget::paintEvent(QPaintEvent *event)
{
    (void)event;
    // 实例化画家对象 this:表示的是在当前窗口中绘画,即绘图设备
    QPainter painter(this);
    // 1. 画一条线
//    painter.drawLine(50, 50, 500, 50);
    // 2. 再画一条线
    painter.drawLine(QPoint(50, 50), QPoint(500, 50));
}

实现效果如下:

界面优化 - 绘图

2.2 绘制矩形

void QPainter::drawRect(int x, int y, int width, int height);

参数:

示例:

void Widget::paintEvent(QPaintEvent *event)
{
    (void)event;
    // 实例化画家对象 this:表示的是在当前窗口中绘画,即绘图设备
    QPainter painter(this);
    // 绘制矩形
    painter.drawRect(100, 100, 300, 150);
}

实现效果如下:

界面优化 - 绘图

2.3 绘制圆形

 void QPainter::drawEllipse(const QPoint ¢er, int rx, int ry)

参数:

示例:

void Widget::paintEvent(QPaintEvent *event)
{
    (void)event;
    // 实例化画家对象 this:表示的是在当前窗口中绘画,即绘图设备
    QPainter painter(this);
    // 绘制圆
    painter.drawEllipse(QPoint(300, 300), 100, 100);
}

实现效果如下:

界面优化 - 绘图

2.4 绘制文本

QPainter类 中不仅提供了绘制图形的功能,还可以使用 QPainter::drawText() 函数来绘制文字,也可以使用 QPainter::setFont() 设置字体等信息。

示例:

void Widget::paintEvent(QPaintEvent *event)
{
    (void)event;
    // 实例化画家对象 this:表示的是在当前窗口中绘画,即绘图设备
    QPainter painter(this);
    // 设置字体
    QFont font("华文行楷", 25);
    painter.setFont(font);
    // 设置画笔颜色
    painter.setPen(Qt::blue);
    // 画文字
    painter.drawText(300, 250, "草长莺飞");
}

实现效果如下:

界面优化 - 绘图

2.5 设置画笔

QPainter 在绘制时,是有一个默认的画笔的。在使用时也可以自定义画笔。在 Qt 中,QPen类中定义了 QPainter 应该如何绘制形状、线条和轮廓。同时通过 QPen类 可以设置画笔的线宽、颜色、样式、画刷等。

画笔的颜色可以在实例化画笔对象时进行设置,画笔的宽度是通过 setWidth() 方法进行设置,画笔的风格是通过setStyle()方法进行设置,画笔的颜色主要是通过 QColor 类设置,设置画刷主要是通过 setBrush() 方法。

画笔的风格有:

界面优化 - 绘图

示例:画笔的使用

void Widget::paintEvent(QPaintEvent *event)
{
    (void)event;
    // 实例化画家对象 this:表示的是在当前窗口中绘画,即绘图设备
    QPainter painter(this);
    // 设置画笔
    QPen pen(QColor(0, 255, 255));
    // 设置画笔宽度
    pen.setWidth(5);
    // 设置画笔风格
    pen.setStyle(Qt::DashLine);
    // 让画家使用画笔
    painter.setPen(pen);
    // 绘制圆
    painter.drawEllipse(QPoint(300, 300), 100, 100);
}

实现效果如下:

界面优化 - 绘图

2.6 设置画刷

在 Qt 中,画刷是使用 QBrush类 来描述,画刷大多用于填充。QBrush定义了QPainter的填充模式,具有样式、颜色、渐变以及纹理等属性。

画刷的格式中定义了填充的样式,使用 Qt::BrushStyle 枚举,默认值是 Qt::NoBrush,也就是不进行任何填充。可以通过 Qt 助手查找画刷的格式。如下图示:

界面优化 - 绘图

设置画刷主要通过 void QPen::setBrush(const QBrush &brush) 方法,其参数为画刷的格式。

示例:

void Widget::paintEvent(QPaintEvent *event)
{
    (void)event;
    // 实例化画家对象 this:表示的是在当前窗口中绘画,即绘图设备
    QPainter painter(this);
    // 设置画刷,给封闭图形填充颜色
    QBrush brush(QColor(255, 0, 255));
    // 设置画刷风格
    brush.setStyle(Qt::DiagCrossPattern);
    // 让画家使用画刷
    painter.setBrush(brush);
    // 绘制圆
    painter.drawEllipse(QPoint(300, 300), 100, 100);
}

实现效果如下:

界面优化 - 绘图

3. 绘制图片

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

3.1 绘制简单图片

1. 新建 Qt 项目,基类选择 QWidget,项目名称为 QPainter。在 "widget.h" 头文件中声明绘画事件;如下图示:

class Widget : public QWidget
{
    Q_OBJECT
public:
    Widget(QWidget *parent = nullptr);
    ~Widget();
    
    // 声明绘画事件
    void paintEvent(QPaintEvent *event);
private:
    Ui::Widget *ui;
};

2. 创建 resource.qrc,并导入图片

界面优化 - 绘图

3. 在 "widget.cpp" 文件中实现画图片功能;

void Widget::paintEvent(QPaintEvent *event)
{
    // 实例化画家对象
    (void)event;
    QPainter painter(this);
    // 画图片
    painter.drawPixmap(0, 0, QPixmap(":/fengche.jpg"));
}

实现效果如下:

界面优化 - 绘图

3.2 平移图片

平移图片实际是通过改变坐标来实现。QPainter类中提供了 translate()函数 来实现坐标原点的改变。

示例:

void Widget::paintEvent(QPaintEvent *event)
{
    // 实例化画家对象
    (void)event;
    QPainter painter(this);
    // 平移图片
    painter.translate(100, 100);
    // 画图片
    painter.drawPixmap(0, 0, QPixmap(":/fengche.jpg"));
}

实现效果如下:

界面优化 - 绘图

3.3 缩放图片

在 Qt 中,图片的放大和缩小可以使用 QPainter类 中的 drawPixmap()函数 来实现。

示例:

void Widget::paintEvent(QPaintEvent *event)
{
    // 实例化画家对象
    (void)event;
    QPainter painter(this);
    QPixmap pixmap(":/fengche.jpg");
    // 缩放图片
    // 以(100,100)点开始画图,图片尺寸变为:400 * 300
    painter.drawPixmap(100, 100, 400, 300, pixmap);
}

实现效果如下:

界面优化 - 绘图

3.4 旋转图片

图片的旋转使用的是 QPainter类 中的 rotate()函数,它默认是以原点为中心进行旋转的。如果要改变旋转的中心,可以使用 translate()函数 完成。

示例:

void Widget::paintEvent(QPaintEvent *event)
{
    // 实例化画家对象
    (void)event;
    QPainter painter(this);
    QPixmap pixmap(":/fengche.jpg");
    // 顺时针旋转 180 度
    painter.rotate(180);
    painter.translate(-800, -600);
    painter.drawPixmap(100, 100, 400, 300, pixmap);
}

实现效果如下:

界面优化 - 绘图

免责声明:由于无法甄别是否为投稿用户创作以及文章的准确性,本站尊重并保护知识产权,根据《信息网络传播权保护条例》,如我们转载的作品侵犯了您的权利,请您通知我们,请将本侵权页面网址发送邮件到qingge@88.com,深感抱歉,我们会做删除处理。