当前位置: 首页 > news >正文

【Qt】Qt界面美化 | 绘画

文章目录

  • 绘画概述
  • 绘制API
    • 1. 图形
      • (1). 线段
      • (2). 矩形
      • (3). 圆形
      • (4). 绘制文本
    • 2. 工具
      • (1). 画笔
      • (2). 画刷
    • 3. 绘制图片
      • QPainter图片操作
    • 绘图设备
      • (1). QPixmap
      • (2). QImage
      • (3). QPicture
  • 结束语

绘画概述

虽然 Qt 已经内置了很多的控件,但还是有很多时候需要“自定义”
Qt 提供了画图相关的API,可以允许我们在窗口上绘制任意的图形形状,来完成更复杂的界面设计。

绘图核心类

说明
QPainter类似“画家”的概念
用来绘图的对象,提供了一系列 drawXXX 方法,允许我们绘制各种图形
QPaintDevice“画板”
描述了 QPainter把图形画到哪个对象上,QWidget 是 QPaintDevice 的子类
QPen“画笔”
描述了 QPainter 画出来的线是什么样的
QBrush“画刷”
描述了 QPainter画出的图形其内部如何填充

绘图 API 的使用,一般不会在 QWidget 构造函数中使用,而是使用事件机制,编写在 paintEvent事件中
paintEvent会在以下情况被触发

  • 控件首次创建
  • 控件被遮挡后,被解除遮挡,重现显现的时候
  • 窗口最小化,再恢复
  • 控件大小发生变化时
  • 主动调用 repaint()或者update()方法(都是 QWidget的方法)

所以要将绘图 API 放在paintEvent中,如果放在构造函数中,则发生上述情况,界面的绘制效果就无法确保符合预期了

绘制API

绘制图形逻辑都是编写在paintEvent

1. 图形

(1). 线段

绘制线段的API为drawLine(),Qt 提供了很多重载版本

API说明
drawLine(int x1, int y1, int x2, int y2)(x1, y1)是线段一端的坐标(x2, y2)是线段另一端的坐标,两点确定一条直线
drawLine(const QLineF &line)QLineF的构造函数也是传入两个坐标,如QLineF(10.0, 80.0, 90.0, 20.0)
drawLine(QPoint &p1, QPoint &p2)传入两个坐标,QPoint(100, 200)

代码示例:

void Widget::paintEvent(QPaintEvent *event)
{(void)event;//避免不必要的警告//画家不用创建在堆上,栈上即可//此处的this,是指定要在哪个界面绘画QPainter painter(this);painter.drawLine(QLineF(100.0, 100.0, 100.0, 300.0));painter.drawLine(100, 100, 275, 275);painter.drawLine(QPoint(100, 100), QPoint(300, 100));}

在这里插入图片描述

(2). 矩形

绘制矩形的API为drawRect()

API说明
drawRect(int x, int y, int width, int height)(x, y)是矩形左上角的坐标,width 和 height分别是宽度和高度

Qt 的坐标是左手坐标系
在这里插入图片描述
代码示例:

void Widget::paintEvent(QPaintEvent *event)
{(void)event;//避免不必要的警告//矩形QPainter painter(this);painter.drawRect(100, 100, 300, 200);
}

在这里插入图片描述

(3). 圆形

绘制圆形的 API 为 drawEllipse()

API说明
drawEllipse(const QPoint &center, int rx, int ry)center 是圆心坐标,rx 和 ry 分别是圆形的外接矩形的宽度和高度
drawEllipse(int x, int y, int width, int height)(x, y)是圆心坐标,width 和 height 含义同 rx 和 ry

在这里插入图片描述
代码示例:

void Widget::paintEvent(QPaintEvent *event)
{(void)event;//避免不必要的警告//圆形QPainter painter(this);painter.drawEllipse(200, 200, 250, 150);
}

在这里插入图片描述

(4). 绘制文本

QPainter 也可以绘制文本
使用QPainter::drawText()绘制文字
使用QPainter::setFont()设置字体等信息

API说明
drawText(int x, int y, const QString &text)文本 text 的左上角坐标为(x, y)
drawText(const QPointF &position, const QString &text)用QPointF 封装坐标
drawText(const QRectF &rectangle, const QString &text)将 text 放入 rectangle矩形内显示

代码示例:

void Widget::paintEvent(QPaintEvent *event)
{(void)event;//避免不必要的警告//文本QPainter painter(this);//设置字体信息QFont font("华文行楷", 20);painter.setFont(font);//绘制文本painter.drawText(QRect(100, 100, 180, 200), "千里之行始于足下");
}

把文本设置在宽180px,高200px的矩形中
在这里插入图片描述

2. 工具

(1). 画笔

QPaint绘制图形时,是有默认的画笔的。但也可以自定义画笔。
QPen 定义了 QPainter 应该如何绘制形状、线条和轮廓。同时通过 QPen 设置画笔的线宽、颜色、样式、画刷

  • setWidth(int width):设置线宽
  • setStyle(Qt::PenStyle style):设置画笔的风格
  • QPen(const QColor &color):设置画笔的颜色

画笔的风格由 Qt::PenStyle 枚举
在这里插入图片描述
代码示例:

void Widget::paintEvent(QPaintEvent *event)
{(void)event;//避免不必要的警告//画笔QPainter painter(this);//初始化画笔,同时设置颜色QPen pen(QColor(255, 0, 0));//设置线宽pen.setWidth(3);//设置风格——虚线pen.setStyle(Qt::DashLine);//设置画笔painter.setPen(pen);//画圆painter.drawEllipse(100, 100, 200, 100);
}

在这里插入图片描述

(2). 画刷

Qt 使用 QBrush封装画刷操作 ,画刷大多用于填充。QBrush 定义了 QPainter 的填充模式,具有样式、颜色、渐变以及纹理等属性
画刷的格式定义了填充的样式,使用 Qt::BrushStyle 枚举,默认值是 Qt::NoBrush(不进行任何填充)
在这里插入图片描述

设置画刷主要通过 setBrush(const QBrush &brush),参数为画刷对象

void Widget::paintEvent(QPaintEvent *event)
{(void)event;//避免不必要的警告//画笔QPainter painter(this);//初始化画笔,同时设置颜色QPen pen(QColor(255, 0, 0));//设置线宽pen.setWidth(3);//设置风格——虚线pen.setStyle(Qt::DashLine);//设置画笔painter.setPen(pen);//画刷QBrush brush(Qt::cyan);//青色//设置风格brush.setStyle(Qt::Dense1Pattern);//设置画刷painter.setBrush(brush);//画圆painter.drawEllipse(100, 100, 200, 100);
}

在这里插入图片描述

3. 绘制图片

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

QPainter图片操作

对图片的操作,同样在paintEvent()事件处理函数中编写

  1. 绘制简单图片

图片资源的添加与管理,参看【Qt】QWidget 的qrc文件部分

void Widget::paintEvent(QPaintEvent *event)
{(void)event;QPainter painter(this);//绘图painter.drawPixmap(0, 0, QPixmap(":/6.jpg"));
}

在这里插入图片描述

  1. 平移图片

平移图片实际是通过改变坐标来实现的,QPainter 提供了 translate()函数来实现坐标原点的改变
其函数原型如下:
在这里插入图片描述
参数(dx, dy)是将坐标原点平移到到(dx, dy)处

代码示例:

void Widget::paintEvent(QPaintEvent *event)
{(void)event;//平移图片QPainter painter(this);painter.translate(100, 100);//绘图painter.drawPixmap(0, 0, QPixmap(":/6.jpg"));
}

在这里插入图片描述

  1. 缩放图片

drawPixmap()的重载函数就可以实现图片的放大和缩小
在这里插入图片描述
通过 width 和 height 控制图片的宽度和高度
代码示例:

void Widget::paintEvent(QPaintEvent *event)
{(void)event;//缩放图片QPainter painter(this);painter.drawPixmap(0, 0, QPixmap(":/6.jpg"));//图片原始大小//将图片缩放成 100 * 100painter.drawPixmap(400, 400, 100, 100, QPixmap(":/6.jpg"));
}

在这里插入图片描述

  1. 旋转图片

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

直接rolate旋转,会导致原先显示界面的图形被旋转到显示界面外

在这里插入图片描述
代码示例:

void Widget::paintEvent(QPaintEvent *event)
{(void)event;//旋转图片QPainter painter(this);painter.translate(200, 200);//先旋转原点painter.rotate(180);//旋转180度painter.translate(-200, -200);//旋转回来painter.drawPixmap(0, 0, QPixmap(":/6.jpg"));
}

在这里插入图片描述

  1. 保存/加载画家状态

在绘制图形的过程中,可以通过save()函数保存画家的状态,如当前原点坐标,旋转情况;使用restore()还原画家状态

代码示例:

void Widget::paintEvent(QPaintEvent *event)
{(void)event;//保存/加载画家状态QPainter painter(this);painter.drawEllipse(100, 100, 100, 100);//画个圆painter.translate(200, 200);//平移原点painter.save();//保存画家状态//新画一个圆painter.drawEllipse(100, 100, 100, 100);painter.translate(300, 300);//再平移painter.restore();//此时恢复画家状态//再画一个圆painter.drawEllipse(100, 100, 100, 100);
}

在这里插入图片描述
第二个圆和第三个圆重合了,因为把加载了之前的画家状态

绘图设备

上述代码都是使用 QWidget作为绘图设备,Qt 还提供了 如下三个绘图设备

  • QPixmap:用于在显示器上显示图片
  • QImage:用于对图片进行像素级修改
  • QPicture:用于对 QPainter 的一系列操作进行存档,是实现回放的一种方式

(1). QPixmap

QPixmap核心特性:

  • 使用 QPainter 直接在上面进行绘制图形
  • 通过文件路径加载并显示图片,或保存图片
  • 搭配 QPainterdrawPixmap()函数,可以把这个图片绘制到 QLabel、QPushButton等控件上
  • 和系统/显示设备强相关,不同系统/显示设备下,QPixmap 的显示可能会有所差别

代码示例:

Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);//绘制图形并保存//Pixmap绘图设备,尺寸设置为500 * 500QPixmap pix(500, 500);QPainter painter(&pix);//实例化画家对象painter.setPen(QPen(Qt::red));//设置画笔颜色painter.drawEllipse(100, 100, 200, 100);//保存绘制的图片pix.save("C:\\Users\\Lenovo\\Desktop\\code\\text.png");
}

在这里插入图片描述

(2). QImage

QImage 核心特性:

  • 使用 QPainter 直接在上面进行绘制图形
  • 通过文件路径加载并显示图片
  • 能够针对图片进行像素级别的操作(操作某个指定的像素)
  • 独立于硬件的绘制系统,能够在不同系统之上提供已知的显示

QImage 的构造函数,还可以设置绘图格式
在这里插入图片描述

代码示例:

Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);//绘图设置的大小为500*500,绘图格式为:QImage::Format_RGB32QImage img(500, 500, QImage::Format_RGB32);img.fill(Qt::white);//设置背景色为白色,默认为黑色QPainter painter(&img);painter.setPen(QPen(Qt::cyan));//设置画笔颜色为青色painter.drawEllipse(100, 100, 100, 100);img.save("C:\\Users\\Lenovo\\Desktop\\code\\img.png");
}

在这里插入图片描述


QImage 也可以用于对图片像素进行修改

  • 通过 setPixel()设置某个像素的颜色值
  • 使用 qRgb 表示一个具体的颜色

代码示例:

void Widget::paintEvent(QPaintEvent *event)
{(void)event;QPainter painter(this);QImage img;img.load(":/1.jpg");//加载图片//修改像素点for(int i = 100; i < 200; ++i){for(int j = 100; j < 200; ++j){QRgb rgb = qRgb(0, 255, 0);img.setPixel(i, j, rgb);}}painter.drawImage(0, 0, img);
}

在这里插入图片描述

(3). QPicture

QPicture 核心特性:

  • 使用 QPainter 直接在上面进行绘制图形
  • 通过文件路径加兹安并显示图片
  • 能够记录 QPainter 的操作步骤
  • 独立于硬件的绘制系统,能够在不同系统之上提供一致的显示

QPicture 类似很多游戏的 Replay(回放功能)
此处的Replay并不是把整个游戏画面都录制下来,而是记录了地图中发生的所有事件(地图元素,玩家单位操作,中立生物行为等…)
当回放 Reply 时就是把上述记录的事件再一条条的执行一遍即可还原之前的游戏场景

如果要记录下 QPainter 的命令,首先要使用 QPainter::begin()函数,将QPicture 示例作为参数传递,以便告诉系统开始记录,记录完毕后使用 QPainter::end()终止
复现时,使用QPicture::load()加载记录,使用QPainter::drawPicture()复现绘图

代码示例:

Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);//QPicture 复现绘图QPainter painter(this);QPicture pic;//开始记录painter.begin(&pic);painter.setPen(QPen(Qt::blue));painter.drawEllipse(200, 200, 150, 150);//终止记录painter.end();//保存记录pic.save("C:\\Users\\Lenovo\\Desktop\\code\\pic.png");
}
void Widget::paintEvent(QPaintEvent *event)
{(void)event;//QPicture 复现绘图QPainter painter(this);QPicture pic;//加载记录pic.load("C:\\Users\\Lenovo\\Desktop\\code\\pic.png");//复现painter.drawPicture(0, 0, pic);
}

如此,每次显示窗口时,都会复现 QWidget 构造函数中的绘图操作
在这里插入图片描述

结束语

Qt 对于界面的优化和美化,还涉及很多知识

  • Qt 动画
  • Qt 3D 图形
  • QQuick
  • 第三方控件库
  • Qt Design Studio

这些都是偏向“设计美工”方面的内容

以上就是本篇博客的所有内容,感谢你的阅读
如果觉得本篇文章对你有所帮助的话,不妨点个赞支持一下博主,拜托啦,这对我真的很重要。
在这里插入图片描述


http://www.mrgr.cn/news/23526.html

相关文章:

  • 【Linux:文件系统】
  • 02 三数排序
  • 枚举专题.
  • 钢铁百科:NM360D执行标准、NM360D焊接性能、NM360D应用范围
  • 第三天旅游线路预览——从禾木景区入口到景区换乘中心
  • 【云服务器介绍】选择指南 腾讯云 阿里云全配置对比 搭建web 个人开发 app 游戏服务器
  • SprinBoot+Vue高校就业管理系统设计与实现的设计与实现
  • Jmeter_循环获取请求接口的字段,并写入文件
  • 无人机动力系统设计之桨叶推力计算
  • 安装一些大模型微调相关的库
  • [苍穹外卖]-07使用缓存优化查询接口
  • 2024年PDF转换器大集合:哪4款是互联网人的首选?
  • TikTok内容电商:短视频与直播带货如何重塑消费者购物决策
  • 国产游戏蓄力,火山引擎ByteHouse助力游戏厂商造爆款
  • DFS算法专题(二)——穷举vs暴搜vs深搜vs回溯vs剪枝【OF决策树】
  • 骨传导耳机哪个牌子值得买?推荐五款表现出色的骨传导耳机!
  • 基于人工智能的个性化学习推荐系统
  • OpenCV结构分析与形状描述符(14)拟合直线函数fitLine()的使用
  • 【C#生态园】JSON数据处理利器盘点:六款C#库全方位对比
  • 如何使用github build安装yolo v8