当前位置: 首页 > article >正文

【Qt】绘图与绘图设备

文章目录

  • 绘图设备
  • QPainter绘图实例
    • 案例1
    • 案例2-高级设置
    • 案例3:利用画家画资源图片 点击按钮移动图片
  • QtPaintDevice实例
    • Pixmap绘图设备
    • QImage 绘图设备
    • QPicture 绘图设备

QPainter绘图

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

  • QPainter用来执行绘制的操作
  • QPaintDevice是一个二维空间的抽象,这个二维空间允许QPainter在其上面进行绘制,也就是QPainter工作的空间
  • QPaintEngine提供了画笔(QPainter)在不同的设备上进行绘制的统一的接口。QPaintEngine类应用于QPainter和QPaintDevice之间,通常对开发人员是透明的

可以把QPainter理解成画笔;把QPaintDevice理解成使用画笔的地方,比如纸张、屏幕等;而对于纸张、屏幕而言,肯定要使用不同的画笔绘制,为了统一使用一种画笔,我们设计了QPaintEngine类,这个类让不同的纸张、屏幕都能使用一种画笔

层次结构

img

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


绘图设备

绘图设备是指继承QPainterDevice的子类,Qt一共提供了四个这样的类:QPixmap、QBitmap、QImage和 QPicture

  • QPixmap专门为图像在屏幕上的显示做了优化
  • QBitmap是QPixmap的一个子类,它的色深限定为1,可以使用 QPixmap的isQBitmap()函数来确定这个QPixmap是不是一个QBitmap,因为QBitmap色深小,因此只占用很少的存储空间,所以适合做光标文件和笔刷。
  • QImage专门为图像的像素级访问做了优化
  • QPicture则可以记录和重现QPainter的各条命令。 QPicture将QPainter的命令序列化到一个IO设备,保存为一个平台独立的文件格式

QPainter绘图实例

案例1

首先需要在Widget文件当中重写绘图事件:

image-20231005155422449


void MainWindow::paintEvent(QPaintEvent *)
{
    //实例化画家对象  this指定的是绘图设备 在当前窗口画画
    QPainter painter(this);

    //设置画笔
    QPen pen(QColor(255,0,0)); //RGB  目前是红笔
    //设置画笔宽度
    pen.setWidth(3);    
    //设置画笔风格
    pen.setStyle(Qt::DotLine);
    //让画家 使用这个笔
    painter.setPen(pen);


    //设置画刷=》对于封闭的图形内部会上色  Qt::cyan  Qt::green 也可以...
    QBrush brush(Qt::cyan); //QBrush brush(QColor(255,0,0)) 也可以
    //设置画刷风格
    brush.setStyle(Qt::Dense7Pattern);
    //让画家使用画刷
    painter.setBrush(brush);


    //画线 =>两点确定一线
    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,150,50) , "好好学习,天天向上");
}
image-20231005155857200

案例2-高级设置

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

//设置 抗锯齿能力=>画的更好  但是效率较低
painter.setRenderHint(QPainter::Antialiasing);
painter.drawEllipse(QPoint(200,50) , 50,50);//画圆


// 画图1->保存点->画图2->恢复到保存点->画图3  所以最后只有画图1和3的矩形
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));

image-20231005160220261


案例3:利用画家画资源图片 点击按钮移动图片

前置工作:

1.在ui界面当中新增加一个按钮:移动图片

2.在mainWidget.h当中新增一个成员:int posX = 0

3.引入资源文件

构造函数

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    //点击移动按钮,移动图片
    connect(ui->pushButton,&QPushButton::clicked,[=](){

        posX+=20;
        //如果要手动调用绘图事件 用update更新
        update();//更新绘图事件
    });

    //开启定时器
    QTimer * timer = new QTimer(this);
    timer->start(10);

    connect(timer,&QTimer::timeout,[=](){
        posX++;
        update();//更新绘图事件
    });

}
void MainWindow::paintEvent(QPaintEvent *)
{
    /利用画家 画资源图片 ///
     QPainter painter(this); //画在当前窗口
     QPixmap pix = QPixmap(":/image/tree.png");

     //如果超出屏幕,重新从0位置开始往右移动
     if(posX >= this->width()) //this->width()屏幕的宽度  this->height()屏幕的高度
     {
         posX = 0;
     }

     painter.drawPixmap(posX,0,pix); //posX:类的成员
}

QtPaintDevice实例

同理也需要重写绘图事件

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

Pixmap绘图设备

//Pixmap绘图设备 会专门为平台做了显示的优化
QPixmap pix(300,300);//相当于300*300的宽 高的纸张

//填充背景颜色
pix.fill(Qt::white);

//声明画家
QPainter painter(&pix);//往pix当中画画

painter.setPen(QPen(Qt::green));//设置画笔颜色
painter.drawEllipse(QPoint(150,150) , 100,100);//画圆

//保存到磁盘的某个位置
pix.save("E:\\pix.png");

QImage 绘图设备

实例1

QImage img(300,300,QImage::Format_RGB32); //宽 高
img.fill(Qt::white);

QPainter painter(&img);
painter.setPen(QPen(Qt::blue));
painter.drawEllipse(QPoint(150,150) , 100,100);

//保存
img.save("E:\\img.png");

可以对像素进行访问

void MainWindow::paintEvent(QPaintEvent *)
{
        QPainter painter(this);

        //利用QImage 对像素进行修改
        QImage img;
        img.load("E:/img.png"); //加载图片

        //修改像素点
        for(int i = 50 ;i < 100 ; i++)
        {
            for(int j = 50 ; j < 100;j++)
            {
                QRgb value = qRgb(255,0,0); //像素点类型
                img.setPixel(i,j,value);//第i行第j列变为value该像素
            }
        }

        painter.drawImage(0,0,img);
}

image-20231005202013208


QPicture 绘图设备

//QPicture 绘图设备  可以记录和重现 绘图指令
QPicture pic;
QPainter painter; //可以后面再指定绘图设备
painter.begin(&pic);  //=>指定绘图设备=>开始往pic上画
painter.setPen(QPen(Qt::cyan));
painter.drawEllipse(QPoint(150,150) , 100,100);
painter.end(); //结束画画

//保存到磁盘
pic.save("E:\\pic.zt"); //名称和后缀名任意

然后可以在绘图事件当中进行重现:

void MainWindow::paintEvent(QPaintEvent *)
{
    //重现QPicture的绘图指令
    QPainter painter(this);

    QPicture pic;
    pic.load("E:\\pic.zt");//加载上述保存的图片的路径
    painter.drawPicture(0,0,pic);
}


http://www.kler.cn/news/108084.html

相关文章:

  • C++不能在子类中构造函数的初始化成员列表中直接初始化基类成员变量
  • C++ 运算符
  • Linux touch命令:创建文件及修改文件时间
  • 底层驱动day8作业
  • 【C++】智能指针:auto_ptr、unique_ptr、share_ptr、weak_ptr(技术介绍 + 代码实现)(待更新)
  • Megatron-LM GPT 源码分析(三) Pipeline Parallel分析
  • AWS SAP-C02教程11-解决方案
  • C#,数值计算——分类与推理,基座向量机的 Svmgenkernel的计算方法与源程序
  • 中微爱芯74逻辑兼容替代TI/ON/NXP工规品质型号全
  • 【杂记】Ubuntu20.04装系统,安装CUDA等
  • python爬虫之feapder.AirSpider轻量爬虫案例:豆瓣
  • PHP简单实现预定义钩子和自定义钩子
  • Linux国产系统无法连接身份证读卡器USB权限解决办法
  • nrf52832 开发板入手笔记:J-Flash 蓝牙协议栈烧写
  • Nginx 的配置文件(负载均衡,反向代理)
  • Spring Security: 整体架构
  • uniapp-图片压缩(适配H5,APP)
  • 10月Java行情 回暖?
  • 【机器学习可解释性】4.SHAP 值
  • 第10期 | GPTSecurity周报
  • scratch接钻石 2023年9月中国电子学会图形化编程 少儿编程 scratch编程等级考试三级真题和答案解析
  • 力扣第763题 划分字母区间 c++ 哈希 + 双指针 + 小小贪心
  • 制作自己的前端组件库并上传到npm上
  • MySQL实战2
  • 华为c语言编程规范
  • 【Unity】RenderFeature应用(简单场景扫描效果)
  • Linux学习第26天:异步通知驱动开发: 主动
  • 基于Headless构建高可用spark+pyspark集群
  • React中useEffect Hook使用纠错
  • 大彩串口屏读写文件问题