2.绘图
Qt提供了画图相关的APL,可以允许我们在窗口上绘制任意的图形形状,来完成更复杂的界面设计
所谓的"控件",本质上也是通过画图的方式画上去的
画图AP|和控件之间的关系,可以类比成机器指令和高级语言之间的关系
控件是对画图API的进一步封装;画图API是控件的底层实现
类 | 说明 |
QPainter | "绘画者"或者"画家" 用来绘图的对象,提供了一系列 |
QPaintDevice | "画板” 描述了 |
QPen | "画笔" 描述了 |
QBrush | "画刷" 描述了 |
绘图API的使用,一般不会在QWidget
的构造函数中使用,而是要放到paintEvent
事件中
关于paintEvent
paintEvent
会在以下情况下被触发:
- 控件首次创建
- 控件被遮挡,再解除遮挡
- 窗口最小化,再恢复
- 控件大小发生变化时
- 主动调用
repaint()
或者update()
方法。(这两个方法都是QWidget
的方法)
因此,如果把绘图 API 放到构造函数中调用,那么一旦出现上述的情况,界面的绘制效果就无法确保符合预期了
①绘制各种形状
1>绘制线段
①:void drawLine(const QPoint &p1,const QPoint &p2);
p1:绘制起点坐标;p2:绘制终点坐标
②:void QPainter:drawRect(int x,int y,int width,int height);
x:窗口横坐标;y:窗口纵坐标;width:所绘制矩形的宽度;height:所绘制矩形的高度;
2>绘制矩形
void QPainter:drawRect(int x,int y,int width,int height);
×:窗口横坐标;y:窗口纵坐标;width:所绘制矩形的宽度;height:所绘制矩形的高度;
3>绘制圆形
void QPainter:drawEllipse(const QPoint ¢er,int rx,int ry);
center:中心点坐标; r×:横坐标; ry:纵坐标
4>绘制文本
#include "widget.h"
#include "ui_widget.h"
#include<QPainter>
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
}
Widget::~Widget()
{
delete ui;
}
void Widget::paintEvent(QPaintEvent *)
{
//实例化画家对象,this表示的是在当前窗口中绘画,即绘图设备
QPainter painter(this);
//画一条线
painter.drawLine(QPoint(20,20),QPoint(200,20));
//再画一条线
painter.drawLine(20,100,200,100);
//绘制矩形
painter.drawRect(120,120,100,50);
//绘制圆
painter.drawEllipse(QPoint(400,200),50,50);
//绘制文本
QFont font("华文行楷",24);
painter.setFont(font);
//设置画笔颜色
painter.setPen(Qt::blue);
//画文字
painter.drawText(QRect(100,200,600,150),"Outlier9");
//坐标如果写成(0,0),就不会显示出来,因为在基线的位置之上
//所以一般y设置为100,基线的位置一般大概在文字的三分之二处
}
5>设置画笔
QPainter
在绘制时,是有一个默认的画笔的。在使用时也可以自定义画笔。在Qt
中,QPen
类中定义了QPainter
应该如何绘制形状、线条和轮廓。同时通过QPen
类可以设置画笔的线宽、颜色、样式、画刷等。
画笔的颜色可以在实例化画笔对象时进行设置
画笔的宽度是通过setWidth()
方法进行设置
画笔的风格是通过setStyle()
方法进行设置
设置画刷主要是通过setBrush()
方法
- 设置画笔颜色:
QPen:QPen(const QColor &color)
画笔的颜色主要是通过QColor类设置; - 设置画笔宽度:
void QPen:setWidth(int width)
- 设置画笔风格:
void QPen:setStyle(Qt:PenStyle style)
画笔风格展示:
画笔使用
#include "widget.h"
#include "ui_widget.h"
#include<QPainter>
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
}
Widget::~Widget()
{
delete ui;
}
void Widget::paintEvent(QPaintEvent *)
{
//实例化画家对象,this表示的是在当前窗口中绘画,即绘图设备
QPainter painter(this);
//设置画笔
QPen pen(QColor(255,0,0));
//设置画笔宽度
pen.setWidth(3);
//设置画笔风格
pen.setStyle(Qt::DashLine);
//设置让画家使用画笔
painter.setPen(pen);
//画一条线
painter.drawLine(QPoint(20,20),QPoint(200,20));
//再画一条线
painter.drawLine(20,100,200,100);
//绘制矩形
painter.drawRect(120,120,100,50);
//绘制圆
painter.drawEllipse(QPoint(400,200),50,50);
//绘制文本
QFont font("华文行楷",24);
painter.setFont(font);
//设置画笔颜色
painter.setPen(Qt::blue);
//画文字
painter.drawText(QRect(100,200,600,150),"Outlier9");
}
6>设置画刷
在Qt中,画刷是使用QBrush
类来描述,画刷大多用于填充。QBrush
定义了QPainter
的填充模式,具有样式、颜色、渐变以及纹理等属性。
画刷的格式中定义了填充的样式,使用Qt:BrushStyle
枚举,默认值是Qt:NoBrush
,也就是不进行任何填充。可以通过Qt助手查找画刷的格式。如下图示:
设置画刷主要通过void QPen:setBrush(const QBrush &brush)
方法,其参数为画刷的格式。
#include "widget.h"
#include "ui_widget.h"
#include<QPainter>
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
}
Widget::~Widget()
{
delete ui;
}
void Widget::paintEvent(QPaintEvent *)
{
//实例化画家对象,this表示的是在当前窗口中绘画,即绘图设备
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.drawLine(QPoint(20,20),QPoint(200,20));
//再画一条线
painter.drawLine(20,100,200,100);
//绘制矩形
painter.drawRect(120,120,100,50);
//绘制圆
painter.drawEllipse(QPoint(400,200),50,50);
//绘制文本
QFont font("华文行楷",24);
painter.setFont(font);
//设置画笔颜色
painter.setPen(Qt::blue);
//画文字
painter.drawText(QRect(100,200,600,150),"Outlier9");
}
②绘制图片
Qt提供了四个类来处理图像数据:QImage
、QPixmap
、QBitmap
和QPicture
,它们都是常用的绘图设备。其中QImage
主要用来进行I/O
处理,它对I/O
处理操作进行了优化,而且可以用来直接访问和操作像素;QPixmap
主要用来在屏幕上显示图像,它对在屏幕上显示图像进行了优化;QBitmap
是QPixmap
的子类,用来处理颜色深度为l的图像,即只能显示黑白两种颜色;QPicture
用来记录并重演QPainter
命令。这里只讲解QPixmap
添加资源文件时,先将准备好的照片都放到一个文件夹内,文件夹与项目文件同级
添加的时候,选中项目文件然后右键add New
然后把图片都添加进去
点击构建并运行,加载资源图片到项目中
图片的平移、放大缩小、旋转
QPainter
类中提供了translate()
函数来实现坐标原点的改变- 图片的放大和缩小可以使用
QPainter
类中的drawPixmap()
函数来实现。 - 图片的旋转使用的是
QPainter
类中的rotate()
函数,它默认是以原点为中心进行旋转的。如果要改变旋转的中心,可以使用translate()
函数完成。
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
//声明绘画事件
void paintEvent(QPaintEvent *event);
private:
Ui::Widget *ui;
};
#endif // WIDGET_H
在绘制图形的过程中,可以通过save()
函数来保存画家的状态,使用restore()
函数还原画家状态。
save()函数原型
restore()函数原型
③特殊的绘图设备
QPixmap
用于在显示器上显示图片QImage
用于对图片进行像素级修改QPicture
用于对QPainter的一系列操作进行存档
1>QPixmap
QPixmap
核心特性:
- 使用
QPainter
直接在上面进行绘制图形. - 通过文件路径加载并显示图片,
- 搭配
QPainter
的drawPixmap()
函数,可以把这个图片绘制到一个QLabel
、QPushButton
等控件上 - 和系统/显示设备强相关,不同系统/显示设备下,QPixmap的显示可能会有所差别
#include "widget.h"
#include "ui_widget.h"
#include<QPixmap>
#include<QPainter>
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
//Pixmap绘图设备,绘图设备尺寸为500*500
QPixmap pix(500,500);
//实例化画家对象
QPainter painter(&pix);
//设置画笔颜色
painter.setPen(Qt::red);
//画图
painter.drawEllipse(QPoint(100,100),100,100);
//保存绘制的图片
pix.save("D:\\C C++\\program\\QT\\QPainter\\picture\\pix.png");
}
Widget::~Widget()
{
delete ui;
}
2>QImage
QImage的核心特性:
- 使用OPainter直接在上面进行绘制图形
- 通过文件路径加载并显示图片
- 能够针对图片进行像素级别的操作(操作某个指定的像素).
- 独立于硬件的绘制系统,能够在不同系统之上提供一致的显示
#include "widget.h"
#include "ui_widget.h"
#include<QPainter>
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
//绘图设备的大小为500*500,绘图格式为QImage::Format_RGB32
//绘图格式可通过Qt助手查看
QImage img(500,500,QImage::Format_RGB32);
img.fill(Qt::white); // 填充色为白色,默认背景色为黑色
QPainter painter(&img); //声明画家,画图设备为img
painter.setPen(QPen(Qt::cyan));//设置画笔颜色为蓝绿色
painter.drawEllipse(QPoint(200,200),100,100); //画圆
//保存图片
img.save("D:\\C C++\\program\\QT\\QImage\\img.jpg");
}
Widget::~Widget()
{
delete ui;
}
QImage
对像素的修改
#include "widget.h"
#include "ui_widget.h"
#include<QPainter>
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
}
Widget::~Widget()
{
delete ui;
}
void Widget::paintEvent(QPaintEvent *)
{
//实例化
QPainter painter(this);
QImage img;
img.load(":/picture/3.png");
//修改像素点
for (int i = 100;i < 200; i++) {
for (int j = 100;j < 200; j++) {
QRgb rgb = qRgb(0,0,255);
img.setPixel(i,j,rgb);
}
}
painter.drawImage(0,0,img);
}
3>QPicture
OPicture核心特性:
- 使用
QPainter
直接在上面进行绘制图形 - 通过文件路径加载并显示图片.
- 能够记录
QPainter
的操作步骤, - 独立于硬件的绘制系统,能够在不同系统之上提供一致的显示
注意:
QPicture
加载的必须是自身的存档文件,而不能是任意的png,jpg
等图片文件
QPicture类似于很多游戏的Replay功能
例如像war3
这样的经典游戏,即使是一场60分钟的膀胱局,生成的replay
文件,也不过几百个KB
此处的Replay
功能并非是把整个游戏画面都录制保存下来,而是记录了地图中发生的所有事件(地图元素,玩家单位操作,中立生物行为等)
当回放Replay
的时候其实就是把上述记录的事件再一条一条的执行一遍即可还原之前的游戏场景了
不了解游戏的同学,也可以理解成警察蜀黍录笔录,并通过笔录还原案发现场
如果要记录下QPainter
的命令,首先要使用QPainter:begin()
函数,将QPicture
实例作为参数传递进去,以便告诉系统开始记录,记录完毕后使用QPainter:end()
命令终止。如下示例:
#include "widget.h"
#include "ui_widget.h"
#include<QPicture>
#include<QPainter>
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
QPicture pic;
QPainter painter;
painter.begin(&pic); // 开始往pic绘图设备上绘画
painter.setPen(QPen(Qt::red)); // 设置画笔颜色为红色
painter.drawEllipse(QPoint(200,200),100,100);
painter.end();//结束绘画
pic.save("D:\\C C++\\program\\QT\\QPicture\\picture\\pic.pic");
}
Widget::~Widget()
{
delete ui;
}
void Widget::paintEvent(QPaintEvent *)
{
QPainter painter(this);
//重现绘图指令
QPicture pic;
pic.load("D:\\C C++\\program\\QT\\QPicture\\picture\\pic.pic");
painter.drawPicture(0,0,pic);
}
④界面优化
其他美化方式包括但不限于:
- Qt动画
- Qt3D图形
- QQuick
- 使用第三方控件库
- Qt Design Studio
这里不做过多介绍了
本站资源均来自互联网,仅供研究学习,禁止违法使用和商用,产生法律纠纷本站概不负责!如果侵犯了您的权益请与我们联系!
转载请注明出处: 免费源码网-免费的源码资源网站 » C++客户端Qt开发——界面优化(绘图)
发表评论 取消回复