17、QtPainter绘图

概述

Qt 的绘图系统允许使用相同的 API 在屏幕和其它打印设备上进行绘制。整个绘图系统基于QPainter,QPainterDevice和QPaintEngine三个类。

QPainter用来执行绘制的操作;

QPaintDevice是一个二维空间的抽象,这个二维空间允许QPainter在其上面进行绘制,也就是QPainter工作的空间;

QPaintEngine提供了画笔(QPainter)在不同的设备上进行绘制的统一的接口。

QPaintEngine类应用于QPainter和QPaintDevice之间,通常对开发人员是透明的。除非你需要自定义一个设备,否则你是不需要关心QPaintEngine这个类的。我们可以把QPainter理解成画笔;把QPaintDevice理解成使用画笔的地方,比如纸张、屏幕等;而对于纸张、屏幕而言,肯定要使用不同的画笔绘制,为了统一使用一种画笔,我们设计了QPaintEngine类,这个类让不同的纸张、屏幕都能使用一种画笔。

下图给出了这三个类之间的层次结构:

上面的示意图告诉我们,Qt 的绘图系统实际上是,使用QPainter在QPainterDevice上进行绘制,它们之间使用QPaintEngine进行通讯(也就是翻译QPainter的指令)。


1. 声明绘图事件(widget.h)

新建一个项目,在widget.h中声明绘图事件void paintEvent();

//绘图事件
void paintEvent(QPaintEvent *);

2. 重写绘图事件(widget.cpp)

widget.cpp中重写绘图事件

#include <QPainter>//画家类
……
void Widget::paintEvent(QPaintEvent *)
{
   
}

2.1. 声明画家对象

首先实例化画家对象,将其绘图设备指定为当前窗口this

//实例化画家对象  this指定的是绘图的设备--->在当前窗口进行绘画
    QPainter painter(this);

2.2. 实现画线、圆、矩形和文字

画线、圆、矩形和文字:

  • 画线——drawLine();
  • 画圆(椭圆)——drawEllipse();
  • 画矩形——drawRect();
  • 画文字——drawText();

函数后面的参数有不同的实现方式,根据Qt中的提示自行决定即可

    //画线
    painter.drawLine(QPoint(0,0),QPoint(100,100));

    //画圆 椭圆
    painter.drawEllipse(QPoint(100,100),50,50);

    //画矩形
    painter.drawRect(QRect(20,20,50,50));

    //画文字
    painter.drawText(QRect(10,200,100,50),"好好学习,天天向上");

效果如下:

2.3. 设置画笔

设置画笔:

  • 设置画笔颜色——pen(QColor());
  • 设置画笔宽度——setWidth();
  • 设置画笔风格——setStyle();
  • 使用画笔——setPen();

注意:

  • 无论是设置画笔的颜色、宽度还是风格,都要在使用这支笔之前设置
  • 笔的默认宽度是1,设为0的话宽度显示也是1
    //设置画笔
    QPen pen(QColor(255,0,0));
    //设置画笔的宽度
    pen.setWidth(3);
    //设置画笔风格
    pen.setStyle(Qt::DotLine);
    //让画家 使用这个笔
    painter.setPen(pen);

效果如下:

2.4. 设置笔刷

设置笔刷:

  • 设置笔刷颜色——brush(QColor());brush(Qt::green);
  • 设置笔刷风格——setStyle();
  • 使用笔刷——setBrush();
    //设置画刷
    //QBrush brush(QColor(0,255,0));
    QBrush brush(Qt::green);
    //设置画刷风格
    brush.setStyle(Qt::CrossPattern);
    //让画家使用画刷
    painter.setBrush(brush);

效果如下:


3. 参考程序文件

11_QPainter.zip


4. QPainter高级设置

4.1. 抗锯齿效果

我们通过设置画家的抗锯齿效果setRenderHint(),可以得到不同精细程度的画,但是相应的,精度越高的画效率的越低。

	QPainter painter(this);
    //画两个圆
    painter.drawEllipse(QPoint(100,50),50,50);
    //设置  抗锯齿能力  效率较低
    painter.setRenderHint(QPainter::Antialiasing);
    painter.drawEllipse(QPoint(200,50),50,50);

效果如下:

可以看出右边的圆,锯齿较少,效果较好

4.2. 对画家进行移动

画家的移动是基于之前保存的画家状态的,通过translate可以移动画家,后面绘制的图形都是基于当前画家位置绘制的,通过restore()我们可以回复到上一个保存的画家状态。

	//画一个矩形
    painter.drawRect(QRect(20,20,50,50));

    //移动画家
    painter.translate(100,0);

    //保存画家状态
    painter.save();

    painter.drawRect(QRect(20,20,50,50));

    painter.translate(100,0);

    //还原画家保存状态
    painter.restore();

    //最后一个和第二个矩形重叠了
    painter.drawRect(QRect(20,20,50,50));

效果如下:

根据代码我们可以分析出,第二个和第三个矩形重合了,因为他们都是基于同一个画家位置绘制的。


5. 高级设置参考代码

    高级设置
//    QPainter painter(this);
//    //画两个圆
//    painter.drawEllipse(QPoint(100,50),50,50);
//    //设置  抗锯齿能力  效率较低
//    painter.setRenderHint(QPainter::Antialiasing);
//    painter.drawEllipse(QPoint(200,50),50,50);


//    //画一个矩形
//    painter.drawRect(QRect(20,20,50,50));

//    //移动画家
//    painter.translate(100,0);

//    //保存画家状态
//    painter.save();

//    painter.drawRect(QRect(20,20,50,50));

//    painter.translate(100,0);

//    //还原画家保存状态
//    painter.restore();

//    //最后一个和第二个矩形重叠了
//    painter.drawRect(QRect(20,20,50,50));

6. 手动调用绘图事件

6.1. 利用画家画图片

注意在Qt中的图片是Pixmap,因此画图片用drawPixmap()函数

    QPainter painter(this);
    painter.drawPixmap(0,0,QPixmap(":/Image/Luffy.png"));

效果如下:

6.2. 手动调用绘图事件

这里我们想点击按钮,实现图片右移。我们先定义一个变量posX代替图片起始点横坐标。

 int posX=0;
 painter.drawPixmap(posX,0,QPixmap(":/Image/Luffy.png"));

然后我们使用信号槽事件,连接按钮和绘图事件,其中手动调用绘图事件使用update()函数,并更新posX的值

 //点击移动按钮,移动图片
    connect(ui->pushButton,&QPushButton::clicked,[=](){
        posX+=20;
        //如果要手动调用绘图事件  用update更新
        update();
    });

同时为了防止图片超出屏幕。我们在绘图事件中添加一个条件判断,当超过屏幕时,将其置0

     QPainter painter(this);

    //如果超出了屏幕  从0开始
    if(posX>this->width()){
        posX=0;
    }

    painter.drawPixmap(posX,0,QPixmap(":/Image/Luffy.png"));

效果如下:

此处为语雀视频卡片,点击链接查看:手动调用绘图事件.mp4


7. 全部参考程序文件

📎11_QPainter(1).zip

  • 22
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值