使用QPainter绘图

    Qt的二维图形引擎是基于QPainter类的,QPainter既可以绘制几何图形(点、线、矩形、弧形、饼状图、多边形、贝塞尔弧线等),也可以绘制像素映射、图像和文字。此外,QPainter也支持一些高级特性,例如反走样(针对文字和图形边缘)、像素混合、渐变填充和矢量路径等,QPainter也支持线性变换,例如平移、旋转、错切和缩放。

    QPainter可以画在“绘图设备”上,例如:QWidget、QPixmap、QIamge或者QSvgGenerator。QPainter也可以与QPrinter一起使用来打印文件盒创建PDF文档。这意味着通常可以用相同的代码在屏幕上显示数据,也可以生成打印形式的报告。

    如果要在绘图设备(一般为窗口部件)上绘图,只需创建一个QPainter,再将指针传到该设备中。

例如:

void MyWidget::paintEvent(QPaintEvent *event)
{
    QPainter painter(this);
}

    使用QPainter的 绘制点drawPoint()、绘制直线drawLine()、绘制折线drawPolyLine()、绘制多点drawPoints()、绘制多直线drawLines()、绘制矩形区域drawRect()、绘制圆角区域drawRoundRect()、绘制椭圆drawEllipse()、绘制背景图片drawPixmap()等函数,可以绘制各种各样的形状.

    绘制效果取决于QPainter的设置,一些是从设备中取得的,然而有些被初始化成默认值。三个主要设置是画笔、画刷、字体:

    画笔:用来画线和边缘。它包含颜色、宽度、线性、拐点风格以及连线风格。

    拐点:FlatCap(平的),SquareCap(方的),RoundCap(圆的),MiterJoin(斜接尖角),BevelJoin(斜接平角),RoundJoin(斜接圆角)

    连线方式:SolidLine(直线),DashLine(虚线),DotLine(点线),DashDotLine(虚点线) ,DashDotDotLine(虚点点线),NoPen(没有线)

    画刷:用来填充几何图形的图案。它一般由颜色和风格组成,但同时也可以是纹理(一个不断重复的图像)或者是一个渐变。

 

    字体:用来绘制文字。字体有很多属性,包括字体族和磅值大小。

    可以随时调用QPen、QBrush或者QFont对象的setPen()、setBrush()和setFont()来修改这些设置。

   

举例:

1、在当前窗口绘制

绘制直线:

void myWidget::paintEvent(QPaintEvent *event)
{
    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing,true);//设置抗锯齿,得到较为平滑的边缘
    painter.setPen(Qt::black); //设置画笔为黑色
    painter.drawLine(0, 0, 100, 100); //(0, 0)为起点坐标,(100, 100)为终点坐标
}

绘制背景图片:

void myWidget::paintEvent(QPaintEvent *event)
{
 QPainter painter(this);
 painter.setRenderHint(QPainter::Antialiasing,true);//设置抗锯齿,得到较为平滑的边缘
 painter.drawPixmap(rect(), QPixmap(skin_name));
}

绘制矩形:

void myWidget::paintEvent(QPaintEvent *event)
{
 QPainter painter(this);
 painter.setRenderHint(QPainter::Antialiasing,true);//设置抗锯齿,得到较为平滑的边缘
 painter.drawRect(20,20,100,60); //设置绘制区域,绘制一个长为80高为40的矩形
}

绘制折线:

void myWidget::paintEvent(QPaintEvent *event)
{
 QPainter painter(this);
 painter.setRenderHint(QPainter::Antialiasing,true);//设置抗锯齿,得到较为平滑的边缘
 painter.setPen(Qt::gray);
 static const QPointF points[4] = {QPointF(0, 30), QPointF(0, this->height()-1), QPointF(this->width()-1, this->height()-1), QPointF(this->width()-1, 30)};
 painter.drawPolyline(points, 4); //由4个点连成的折线
}

绘制椭圆:

void myWidget::paintEvent(QPaintEvent *event)
{
 QPainter painter(this);
 painter.setRenderHint(QPainter::Antialiasing,true);//设置抗锯齿,得到较为平滑的边缘
 painter.setPen(QPen(Qt::black,12,Qt::SolidLine,Qt::RoundCap));//设置画笔黑色,12像素,实线,圆拐角
 painter.setBrush(QBrush(Qt::green,Qt::SolidPattern));//设置画刷绿色无缝填充
 painter.drawEllipse(80,80,400,240);//绘制椭圆
}

绘制圆:

void myWidget::paintEvent(QPaintEvent *event)
{
 QPainter painter(this);
 painter.setRenderHint(QPainter::Antialiasing,true);//设置抗锯齿,得到较为平滑的边缘
 painter.setPen(QPen(Qt::black,12,Qt::SolidLine,Qt::RoundCap));//设置画笔黑色,12像素,实线,圆拐角
 painter.setBrush(QBrush(Qt::green,Qt::SolidPattern));//设置画刷绿色无缝填充
 painter.drawEllipse(80,80,200,200);//绘制圆 长宽相等 绘制正圆
}

绘制圆角:

setWindowFlags(Qt::FramelessWindowHint); //去掉标题栏
setAttribute(Qt::WA_TranslucentBackground); //不被绘制上的部分设置透明
void myWidget::paintEvent(QPaintEvent *event)
{
 QPainter painter(this);
 painter.setRenderHint(QPainter::Antialiasing,true);//设置抗锯齿,得到较为平滑的边缘
 QBrush brush;
 brush.setTextureImage(QImage(background_image));
 painter.setBrush(brush); //设置画刷,绘制背景图片
 painter.setPen(Qt::black); //设置画笔,绘制边框色       
 painter.drawRoundedRect(QRect(0, 0, this->width()-1, this->height()-1), 5, 5); //绘制圆角,像素为5
}

绘制饼状图:

void myWidget::paintEvent(QPaintEvent *event)
{
 QPainter painter(this);
 painter.setRenderHint(QPainter::Antialiasing,true);//设置抗锯齿,得到较为平滑的边缘
painter.setPen(QPen(Qt::black,12,Qt::SolidLine,Qt::RoundCap,Qt::MiterJoin));//设置画笔黑色,12像素,实线,圆拐角
 painter.setBrush(QBrush(Qt::blue,Qt::DiagCrossPattern));//设置画刷蓝色纹理填充
 painter.drawPie(80,80,400,240,60*16,270*16);//最后两个参数以1/16度为单位
//所以绘制了一个从60度-270度的饼状图
}

绘制贝塞尔曲线:

void myWidget::paintEvent(QPaintEvent *event)
{
 QPainter painter(this);
 painter.setRenderHint(QPainter::Antialiasing,true);//设置抗锯齿,得到较为平滑的边缘

 QPainterPath path;//QPainterPath类确定绘制图形的路径
 path.moveTo(80,320);//起点位置
 path.cubicTo(200,80,320,80,480,320);//路径依次经过点
 painter.setPen(QPen(Qt::black,8));//设置画笔黑色,12像素
 painter.drawPath(path);//绘制路径
}

2、在当前窗体上的子组件绘制

    paintEvent()可以实现图形的绘制,前提是绘制当前窗体!如果界面上有其它组件,如何来绘制呢?

   (1)对子组件自定制,可以重新实现一个类,实现paintEvent()

   (2)添加监听器line_label->installEventFilter(this),实现eventFilter()。

    关于(1)就不再多讲,同1,(2)代码如下:

line_label->installEventFilter(this);
bool myWidget::eventFilter(QObject *obj, QEvent *event)
{
 if(obj == line_label)
 {
  if(event->type() == QEvent::Paint)
  {
   int label_height = line_label->height();
   int label_width = line_label->width();
   QPainter painter(line_label);
   painter.setPen(QPen(Qt::gray, 1, Qt::DashLine));
   painter.drawLine(label_width/2, 0, label_width/2, label_height); 
  }
 }
 return QWidget::eventFilter(obj, event);
}

    这样就可以实现在myWidget窗体上的QLabel的绘制!

    优劣性:如果窗口子部件较多,若每个部件的绘制相同,则可采用(1),若不相同,那么根据(1)就会实现较多的类,而(2)只需要添加多个监听器即可,建议采用方式(2)!

    就我所知,setAttribute(Qt::WA_TranslucentBackground)有一定的弊病,当窗体最小化(showMinimized())后,再次显示时,窗体上的组件就会失去焦点!

    好了,二维绘图基本就介绍到这里,代码实现可以不尽相同,只要掌握原理,实现起来就会游刃有余!

  • 0
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

落雪飘茗

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值