个人主页~
绘图
一、绘图1、基础内容2、绘制形状(1)线段(2)矩形(3)圆形(4)文本(5)画笔(6)画刷 3、绘制图片(1)简单图片(2)旋转图片 4、其他(1)移动画家位置(2)保存、加载画家的状态 5、其他(1)QPixmap(2)QImage修改像素点 (3)QPicture
一、绘图
1、基础内容
绘图可以帮助我们实现应对多种场景的功能,因为虽然Qt内部内置了很多控件,但是它们不能满足所有要求,我们就可以通过绘图来实现自定义图形
API核心类 | 说明 |
---|---|
QPainter | 用来绘画的对象,可以允许我们绘制各种图形 |
QPaintDevice | 描述QPainter把图形画到哪个对象上 |
QPen | 描述QPainter画出来的线 |
QBrush | 描述QPainter填充一个区域 |
一般绘图API的使用会放到paintEvent事件中,当控件首次创建、控件被遮挡再解除遮挡、窗口最小化再回复、控件大小发生变化、主动调用repaint或update方法时,paintEvent会被触发
2、绘制形状
下面只有线段是写在paintEvent里面的,其实它们都是要重写paintEvent函数的,为了简短表达,所以除了第一个其他的都没写出函数以及大括号和定义painter的部分
(1)线段
void Widget::paintEvent(QPaintEvent *event){ QPainter painter(this); //参数为坐标(QPoint) painter.drawLine(QPoint(30,20),QPoint(300,200));//参数两个一组,为坐标(int) painter.drawLine(40,50,400,500);}
(2)矩形
//参数从左到右依次是窗口横坐标、窗口纵坐标、所绘制矩形的宽、所绘制矩形的高painter.drawRect(20,20,200,50);
(3)圆形
//从左到右参数依次是圆心坐标,离圆心的x距离,离圆心的y距离painter.drawEllipse(QPoint(100,100),100,100);
(4)文本
//设置字体QFont font("楷体",30);painter.setFont(font);//设置画笔颜色painter.setPen(Qt::blue);//画文本painter.drawText(QRect(50,100,800,200),"超级小小怪-s_little_monster");
(5)画笔
QPen类控制画笔,它定义了QPainter绘制什么样的形状、线条和轮廓,以及设置画笔的线宽、颜色、样式、画刷
画笔颜色可以在实例化画笔对象时进行设置,画笔的宽度是通过setWidth()方法进行设置,画笔的风格是通过setSytle()方法进行设置,设置画刷主要是通过setBrush()方法
//画笔颜色QPen::QPen(const QColor& color);//画笔宽度void QPen::setWidth(int width);//画笔风格void QPen::setSytle(Qt::PenSytle style);
以下是画笔的风格:
(6)画刷
用QBrush类描述,大多用于填充,具有样式、颜色、渐变、纹理等属性
以下是画刷的风格:
//设置画笔QPen pen(QColor(155,155,255));//画笔宽度pen.setWidth(5);//画笔风格pen.setStyle(Qt::DashLine);//将画笔设置到画家手中painter.setPen(pen);//设置画刷,设置为青色(cyan)QBrush brush(Qt::cyan);//画刷风格brush.setStyle(Qt::Dense1Pattern);//画家拿画刷painter.setBrush(brush);//画圆painter.drawEllipse(QPoint(200,200),100,100);
3、绘制图片
(1)简单图片
//移动图片基点(基点默认为左上角)painter.translate(100,100);//绘制图片painter.drawPixmap(0,0,QPixmap(":/picture/slm.jpg"));//移动图片基点+改变图片尺寸+绘制图片painter.drawPixmap(300,400,60,40,QPixmap(":/picture/slm.jpg"));
(2)旋转图片
painter.translate(300,300);//对坐标系进行180°旋转(顺时针)painter.rotate(180);//使原点从(300,300)移动回到(0,0)painter.translate(-300,-300);//画图片painter.drawPixmap(0,0,QPixmap(":/picture/slm.jpg"));
这里详细解释一下,第一行代码将图片移动到(300,300)此时旋转的基点就是(300,300),旋转180°之后的图片是下面这样的
原来我们的坐标系是向上y减小,向左x减小,此时坐标系180°旋转,变成了向上y增大,向左x增大,所以现在将基点移动到(-300,-300)就是向下移动300个像素,向右移动300个像素
4、其他
(1)移动画家位置
painter.drawEllipse(QPoint(100,100),100,100);//移动画家位置,此时(200,0)就是下个圆的(0,0)基点painter.translate(200,0);painter.drawEllipse(QPoint(100,100),100,100);
(2)保存、加载画家的状态
save函数保存画家状态
restore函数还原画家状态
比如上面的程序可以稍加改造
painter.drawEllipse(QPoint(100,100),100,100);painter.translate(200,0);//保存状态painter.save();painter.drawEllipse(QPoint(100,100),100,100);painter.translate(200,0);//恢复状态painter.restore();painter.drawEllipse(QPoint(100,100),100,100);
我们发现第三个圆没有出现,其实是跟第二个圆重叠了,就是因为画家恢复了状态,导致画家的移动失效了
5、其他
(1)QPixmap
//画布大小QPixmap map(600,600);//实例化画家QPainter painter(&map);//画笔颜色painter.setPen(Qt::green);//画圆painter.drawEllipse(QPoint(100,100),100,100);//保存绘制的图片map.save("C:\\Users\\14725\\Desktop\\map.png");
(2)QImage
//设置画布大小以及绘图格式,绘图格式可在Qt助手中查看QImage img(600,600,QImage::Format_RGB32);//填充色为白色,默认为黑色img.fill(Qt::white);QPainter painter(&img);//画笔颜色painter.setPen(Qt::green);//画圆painter.drawEllipse(QPoint(100,100),100,100);img.save("C:\\Users\\14725\\Desktop\\img.png");
修改像素点
void Widget::paintEvent(QPaintEvent *event){ QPainter painter(this); QImage img; img.load(":/picture/slm.jpg"); //将长方形内的像素都改为红色 for(int i = 100;i<300;i++) { for(int j = 100;j <200;j++) { QRgb rgb = qRgb(255,0,0); img.setPixel(i,j,rgb); } } //将这个图画出来 painter.drawImage(0,0,img);}
(3)QPicture
QPicture类似于游戏中的replay功能,replay可以通过记录地图中发生的所有事件,当回放replay的时候其实就是把上述记录的事件再一条一条的执行一遍就可以还原游戏场景了,这就大大节约了我们存储该内容的空间,当然它只能加载自己生成的文件,不能加载其他的文件
要使用begin和end配套,首先使用begin将QPicture实例作为参数传递进去,告诉系统开始记录,记录完毕后用end结束
Widget::Widget(QWidget *parent) : QWidget(parent) , ui(new Ui::Widget){ ui->setupUi(this); QPicture picture; QPainter painter; //开始在画布上画画 painter.begin(&picture); //设置画笔颜色 painter.setPen(Qt::red); painter.drawEllipse(QPoint(100,100),100,100); //结束画画 painter.end(); picture.save("C:\\Users\\14725\\Desktop\\picture.pic");}void Widget::paintEvent(QPaintEvent *event){ QPainter painter(this); //重现画图指令 QPicture picture; picture.load("C:\\Users\\14725\\Desktop\\picture.pic");//加载图片 painter.drawPicture(0,0,picture);}
后缀为pic无法直接打开,只能通过重现绘图指令来打开
今日分享就到这了~