部分资料参考自:c++开发指南
,按照书本的流程,筛选了重要内容,代码上做了很多填充和修补。
1、基本绘图属性:
基本绘图类:
QPainter
、QPaintDevice
和QPaintEngine
。
QPaintDevice
类表示QPainter
的绘图设备,QPainter
能在QPaintDevice
的子类上进行图形绘制,QpaintDevice
子类包含QImage
、QOpenGLPaintDevice
、QWidget
、QPixmap
、PixelBuffer
、QGLFramebufferObject
、QPicture
、QPrinter
。
绘图事件:
void wiget::paintEvent(QPaintEvent *event){}
QPainter
只能在paintEvent
中进行绘图。paintEvent
事件在窗口刷新时触发,如最大化最小化,拖动窗口边缘时也会触发。
主要属性:
(1) QPen
:控制线条颜色宽度线性。
(2) QBrush
:设置一个区域的填充特性。
(3) QFont
:用于绘制文字。
(4) QPixmap
: 绘制图片,适合小图片。
(5) QImage
: 绘制图片,适合大图片。
(6) QBitmap
: QPixmap
的一个子类,单通道图。
(7) QPicture
: 一张画布,可以用于保存、读取Qpainter
的绘图。
基本图形绘制函数:
drawPoint() //画点
drawLine() //画直线
drawRect() //画矩形
drawArc() //画圆弧
drawEllipse() //画椭圆
drawPie() //画扇形
drawPolygon() //画多边形
drawChord() //画弦
drawRoundedRect() //画圆角矩形
drawPolyline() //画折线
drawConvexPolygon() //画凸多边形
2、基本使用:
在mianwindow.h
中引入QPainter
及其他常用模块:
#include <QPainter>
#include <QBitmap>
#include <QPixmap>
#include <QPicture>
声明Qpainter
事件:
protected:
void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE;
//Q_DECL_OVERRIDE表示这个函数是对父类虚函数的重载
在窗体中绘制图形代码+代码分析注释:
部分代码参考自:https://www.cnblogs.com/lifexy/p/9203929.html
mainwindow.cpp
中添加代码:
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
setPalette(QPalette(Qt::white)); //设置窗口为白色背景
setAutoFillBackground(true); //设定背景时一定要设置setAutoFillBackground
}
//界面刷新时会触发paint事件,如最大化最小化、拖动窗口边缘时也会触发
void MainWindow::paintEvent(QPaintEvent *event)
{
QPainter painter(this); //创建QPainter对象
painter.setRenderHint(QPainter::Antialiasing); //边的反锯齿绘制
painter.setRenderHint(QPainter::TextAntialiasing); //文字的反锯齿绘制
painter.setRenderHint(QPainter::SmoothPixmapTransform); //用平滑的pixmap变换算法
//把图像上的图形绘制到窗口中(三通道+单通道),单色通道图会受画刷颜色影响,所以最好放在画笔画刷设置之前。
QPixmap pixmap(":/new/prefix1/source/pic1.png"); //QPixmap继承了QPaintDevice,可直接进行绘图
QBitmap bitmap(":/new/prefix1/source/pic1.png"); //QBitmap继承自QPixmap,只提供单色通道
painter.drawPixmap(10, 10, 58, 58, pixmap);
painter.drawPixmap(80, 10, 58, 58, bitmap);
//设置画笔(会作用于之后的元素)
QPen pen;
pen.setWidth(3); //宽度
pen.setColor(Qt::red); //划线颜色
pen.setStyle(Qt::SolidLine); //线的样式,实线、虚线等
pen.setCapStyle(Qt::FlatCap); //线端点的样式
pen.setJoinStyle(Qt::BevelJoin); //线的连接点样式
painter.setPen(pen); //设置画笔
//设置画刷
QBrush brush;
brush.setColor(Qt::yellow); //画刷颜色
brush.setStyle(Qt::SolidPattern); //画刷填充样式
painter.setBrush(brush); //设置画刷
//画椭圆
painter.drawEllipse(10, 80, 70, 70); //前两个参数是坐标,后两个是容纳椭圆的矩形区域长宽
//画点
painter.drawPoint(90,90); //绘制中心点
//画矩形
int W=this->width(); //绘图区宽度
int H=this->height(); //绘图区高度
QRect rect(W/5,H/50,W/10,H/10); //前两个参数是坐标,后两个是长宽
//执行矩形绘图操作
painter.drawRect(rect); //上面只是创建了一个矩形的对象,将这个矩形画到画布上还需要用drawRect
//矩形中画圆弧
painter.drawArc(rect,30*16,160*16); //绘画角度为30°~(30+150°)
//添加文字
QFont font1;
font1.setPixelSize(24); //设置字体像素大小为12
QString text="hello"; //设置显示的文本
QFontMetrics metrics(font1); //获取文字宽度对象
int w=metrics.width(text); //获取显示文本的宽度
int h=metrics.height(); //获取显示文本的高度
painter.setFont(font1);
painter.setPen(Qt::blue);
painter.drawText(QRect(this->width()/2-w,this->height()/2-h,w,h),text);
//文字也可以不画矩形,直接设置坐标就行了,代码如下:
//painter.drawText(270,420,u8"hello!");
//画线,以下4个参数分别为线段两端点坐标
painter.drawLine(180,180,300,180);
}
MainWindow::~MainWindow()
{
delete ui;
}
运行结果:
3、QPen的一些属性与功能:
主要函数:
//函数原型 功能
void setColor(QColor &color) //设置画笔颜色
void setWidth(int width) //设置线条宽度
void setStyle(Qt::PenStyle style) //设置线条样式,参数为Qt::PenStyle枚举类型
void setCapStyle(Qt::PenCapStyle style) //设置线条端点样式,参数为Qt::PenCapStyle枚举类型
void setJoinStyle(Qt::PenJoinStyle style)//设置连接样式,参数为Qt::PenJoinStyle枚举类型
属性修改后,需要使用setPen()
来应用于绘图。
(1)线条样式:
Qt::NoPen //没有画笔,设置此属性时,用画笔不会画出任何东西。但是画刷仍然有效,表现出来就是无边界,但有填充。
Qt::SolidLine //实线
Qt::DashLine //虚线
Qt::DotLine //点状线
Qt::DashDotLine //虚线和点交替
Qt::DashDotDotLine //虚线和双点交替
Qt::CustomDashLine //自定义样式
(2)线条端点样式:
Qt::FlatCap //平顶端点
Qt::SquareCap //方形端点
Qt::RoundCap //圆形端点
(注: 三条线的预设坐标长度是一样长的)
(3)线条连接样式:
Qt::BevelJoin //斜切连接
Qt::MiterJoin //直角连接
Qt::RoundJoin //圆连接
拿直线画了半天发现没效果,后来想到即使点重合的两条直线,也没有连接关系,所以要么画折线,要么画多边形。
这里我画了三个正方形来演示:
4、QBrush的一些属性与功能:
主要函数:
// 函数原型 功能
void setColor(QColor &color) //设置画刷颜色
void setStyle(Qt::BrushStyle style) //设置画刷样式
void setTexture(QPixmap &pixmap) //设置一个QPixmap图片作为画刷的图片
void setTextureImage(QImage &image) //设置一个QImage类型的图片作为画刷的图片
(1)基本填充和线性填充:
//枚举常量 描述
Qt::NoBrush //不填充
Qt::SolidPattern //单一颜色填充
Qt::HorPattern //水平线填充
Qt::VerPattern //垂直线填充
(2)渐变填充:
Qt::LinearGradientPattern //线性渐变,需要使用QLinearGradient类对象作为Brush
Qt::RadialGradientPattern //辐射渐变,需要使用QRadialGradient类对象作为Brush
Qt::ConicalGradientPattern //圆锥型渐变,需要使用QConicalGradient类对象作为Brush
Qt::TexturePattern //材质填充,需要指定texture或textureImage图片
线性渐变使用时:
在paintEvent
中添加:
QLinearGradient linearGradient(QPointF(40,190),QPointF(70,190));
//从点(40,190)到(70,190)确认一条直线
//插入颜色(长度为分段)
linearGradient.setColorAt(0,Qt::yellow);
linearGradient.setColorAt(0.3,Qt::blue);
linearGradient.setColorAt(0.5,Qt::red);
linearGradient.setColorAt(0.8,Qt::black);
linearGradient.setColorAt(1,Qt::green);
//指定渐变区域以外的区域的扩散方式
linearGradient.setSpread(QGradient::RepeatSpread); //重复传播
//使用渐变作为画刷
painter.setBrush(linearGradient);
QRect rect1(200,180,50,50);
painter.drawRect(rect1);
painter.drawText(270,210,u8"线性渐变");
运行结果:
辐射渐变使用时:
在paintEvent
中添加:
QRadialGradient radialgradient(225,205,25,25,25); //第1、2位为辐射渐变的圆心位置坐标,第3位为半径,第4、5两位是焦点的位置坐标(没错,就是辐射渐变中间的点)
//颜色分段(半径为分段)
radialgradient.setColorAt(0,Qt::red);
radialgradient.setColorAt(0.5,Qt::blue);
radialgradient.setColorAt(1,Qt::green);
//指定渐变区域以外的区域的扩散方式
radialgradient.setSpread(QGradient::RepeatSpread); //重复传播
//使用渐变作为画刷
painter.setBrush(radialgradient);
QRect rect1(200,180,50,50);
painter.drawRect(rect1); //不一定是矩形,也可以是圆形。必须要有载体,填充方式无法单独存在
painter.drawText(270,210,u8"辐射渐变");
运行结果:
圆锥型渐变的使用:
在paintEvent
中添加:
QConicalGradient conicalgradient(225,205,5); //前两位为中心点坐标(相对于整个屏幕坐标),最后一个参数为角度为20
//添加颜色,按角度分段
conicalgradient.setColorAt(0,Qt::red);
conicalgradient.setColorAt(0.3,Qt::black);
conicalgradient.setColorAt(0.5,Qt::blue);
conicalgradient.setColorAt(0.8,Qt::yellow);
conicalgradient.setColorAt(1,Qt::green);
conicalgradient.setSpread(QGradient::RepeatSpread); //重复传播
//使用渐变作为画刷
painter.setBrush(conicalgradient);
QRect rect1(200,180,50,50);
painter.drawRect(rect1); //不一定是矩形,也可以是圆形。必须要有载体,填充方式无法单独存在
painter.drawText(270,210,u8"圆锥型渐变");
运行结果: