qt 绘图QPainter

2023-11-14

QPainter绘图系统

QPainter用来进行绘图操作的类。绘图设备一般包括Qwidget、Qpixmap、QImage.他们提供给QPainter画布。
QPaintDevice是一个可以使用QPainter进行绘图的抽象二维界面。
QPaintEngine给QPainter提供在不同设备上绘图的接口,QPaintEngine类由QPainter和QPaintDevice内部使用,应用程序一般无需使用QPaintEngine。
绘图设备包括QWidget、QPixmap、QImage等。


paintEvent世界和绘图区

QWidget类及其子类是最常用的绘图设备,从QWidget类继承的类都有paintEvent()事件,只需要重定义此事件就行。  相当于windows mfc的onpaint函数。paintEvent里面的坐标默认是物理坐标(视口坐标)

只要窗口部件需要被重绘就被调用。是repaint()或update()的结果。 几次调用update()的结果通常仅仅是一次paintEvent()调用。 Qt通常在paintEvent()调用之前擦除这个窗口部件的区域。

update()相当于 mfc 的invalidate();迫使paintEvent虚函数被调用。

QWidget绘图区就是其窗口内部区域。坐标系统的单位是像素。左上角坐标为(0,0)。这个坐标系统是物理坐标,称为视口(viewport)坐标

高度:QWidget::height()

宽度:QWidget::width()

设置qwidget窗口大小的函数

1.setMinimumSize(固定最小大小) setMaximumSize(固定最大大小)  能够设置初始大小

2.setFixedSize   固定大小,  能够设置初始大小,但是之后就不能用鼠标调整窗口大小了

3.resize   推荐使用的方法

4.setGeometry 

延伸到控件的缩放方式sizePolicy

控件的 sizePolicy 说明控件在布局管理中的缩放方式。调用setsizepolicy函数实现。默认是按比例缩放的。

Fixed:控件不能放大或者缩小,控件的大小就是它的sizeHint。
Minimum:控件的sizeHint为控件的最小尺寸。控件不能小于这个sizeHint,但是可以
放大。
Maximum:控件的sizeHint为控件的最大尺寸,控件不能放大,但是可以缩小到它的最小的允许尺寸。
Preferred:控件的sizeHint是它的sizeHint,但是可以放大或者缩小
Expandint:控件可以自行增大或者缩小

 m_paddBtn = new QPushButton(tr("添加"));
m_paddBtn->setSizePolicy(QSizePolicy::Fixed,QSizePolicy::Fixed);

延伸到控件的大小sizeHint

这个属性所保存的 QSize 类型的值是一个被推荐给窗口或其它组件(为了方便下面统称为widget)的尺寸,也就是说一个 widget 该有多大,它的一个参考来源就是这个 sizeHint 属性的值,而这个值由 sizeHint() 函数来确定。

1.在 widget 有 layout 的情况下,其 sizeHint() 函数返回的是有效值作为其自身实际尺寸的参考;
2. sizeHint() 返回的值并不一定会作为 widget 的实际尺寸,因为 widget 的尺寸的决定还有其它因素作用;

sizeHint为虚函数,重写该函数即可。virtual QSize sizeHint() const;

QPainter绘图主要属性

QPen:画笔,用于控制线条的颜色、宽度等。   

setPen、setStyle(线条样式)、setCapStyle(线条端点样式)、setJoinStyle(线条连接样式)

QBrush:画刷,用于填充颜色、渐变特性等。

  setBrush、setStyle(填充样式)

渐变色:

线性渐变:QLinearGradient

辐射渐变:QRadialGradient

圆锥形渐变:QConicalGradient

//线性渐变
    QLinearGradient  linearGrad(0,0,100,0);//从左到右,
    linearGrad.setColorAt(0,Qt::yellow);//起点颜色
    linearGrad.setColorAt(1,Qt::green);//终点颜色
    linearGrad.setSpread(QGradient::PadSpread);  //展布模式
    painter.setBrush(linearGrad);

QFont:字体属性,用于绘制文字时,设置文字的样式、大小等 

setFont

绘图

点:drawPoint()、drawPoints()、

线:drawLine()、

区域:drawRect()

文本:drawText()

Qt提供了处理图像数据的类:QImage, QPixmap和QPicture。

  • QImage是为I/O和直接像素访问和操作而设计和优化的
  • QPixmap是为在屏幕上显示图像而设计和优化的。
  • QPicture类是一个记录和回放QPainter命令的绘制设备。

drawPicture: QPicture 

 QPicture picture;
 QPainter painter;
 painter.begin(&picture);           // paint in picture
 painter.drawEllipse(10,20, 80,70); // draw an ellipse
 painter.end();                     // painting done
 picture.save("drawing.pic");       // save picture


QPicture picture;
QPainter painter;
picture.load("drawing.pic");
painter.begin(this);
painter.drawPicture(0,0,picture);
painter.end();

drawPixmap:   QPixmap

QPixmap绘图依赖硬件,QPixmap的设计本来就是用来加速显示,用paint绘图时用QPixmap会比其他类的效果好很多。一般小图片用QPixmap加载,和平台相关(在不同的平台可能绘制出的效果不一样)。QPixmap上绘图比较慢,但显示它则比较快(使用GPU处理,相对减轻了CPU的负担).

可以直接使用构造函数,关联资源 ,如 QPixmap(":/res/python.jpg");也可以使用load、save进行加载或保存。

load() 加载图像文件作为QPixmap对象
save() 将QPixmap对象保存为文件

QPximap在label中的使用:(其他按键控件也可使用)

    QLabel *label=new QLabel(this);
    label->resize(303,303);//设置大小
    QPixmap pixmap(":/image/456.png");
    pixmap.scaled(label->width(),label->height());
    label->setPixmap(pixmap);

QPximap 在widget的paintevent函数绘制

void Widget::paintEvent(QPaintEvent *event)
{
    QPainter painter(this);
    QRect rect1(0,0,100,100);
    paint.drawPixmap(rect1,QPixmap(tr(":/res/about.png")));
}


    

 QPximap ​​​​​​​对象保存


QPixmap pixmap(width, height);
QPainter painter(&pixmap);
调用painter的函数画图
pixmap.save(PATH); //保存绘制好的图像

drawImage   QImage

QImage类提供了一个独立于硬件的图像表示,它允许直接访问像素数据,并且可以用作绘制设备;适合加载大图片;可以在线程中绘图,可以优化UI响应时间。绘制图片出来的效果和平台无关,QImage上绘图比较快,但显示它则比较慢。

QImage的基本函数的使用与QPixmap类似,可以直接使用构造函数,关联资源

    QRect rect2(100,0,100,100);
    paint.drawImage(rect2,QImage(tr(":/res/about.png")));

QPixmap与QImage的区别:

QPixmap依赖于硬件,QImage不依赖于硬件。

QPixmap主要是用于绘图,针对屏幕显示而最佳化设计,QImage主要是为图像I/O、图片访问和像素修改而设计的。
当图片小的情况下,直接用QPixmap进行加载,画图时无所谓,当图片大的时候如果直接用QPixmap进行加载,会占很大的内存,一般一张几十K的图片,用QPixmap加载进来会放大很多倍。

所以一般图片大的情况下,用QImage进行加载,然后转乘QPixmap用户绘制。QPixmap绘制效果是最好的。

QImage image = pixmap.toImage();
QPixmap pixmap = QPixmap::fromImage(image);

坐标平移:translate

坐标旋转:rotate

缩放:scaled

状态保存 save

状态恢复    restore

恢复所有操作: resetTransform

坐标

物理坐标:

视口坐标setviewport  默认情况下,视口等于绘图设备的整个矩形区。单位为像素

逻辑坐标:

窗口坐标,中心为原点(0,0)setwindow  如果想不用管实际物理坐标范围大小,可通过设置成窗口坐标来绘图。这是设备大小变化时,绘制的图片也自动变化大小。

调用setwindow后,后面用到的坐标都是按逻辑坐标来算了的。是按比例缩放

void Widget::paintEvent(QPaintEvent *event)
{
    Q_UNUSED(event);
    QPainter    painter(this);

    int W=width();
    int H=height();

    int side=qMin(W,H);//去长和宽的小值
    QRect rect((W-side)/2, (H-side)/2,side,side); //viewport矩形区
    painter.drawRect(rect); //Viewport大小

    painter.setViewport(rect);//设置Viewport
    painter.setWindow(-100,-100,200,200); // 设置窗口大小,逻辑坐标

    painter.setRenderHint(QPainter::Antialiasing);

//设置画笔
    QPen    pen;
    pen.setWidth(1); //线宽
    pen.setColor(Qt::red); //划线颜色
    //Qt::NoPen,Qt::SolidLine, Qt::DashLine, Qt::DotLine,Qt::DashDotLine,Qt::DashDotDotLine,Qt::CustomDashLine
    pen.setStyle(Qt::SolidLine);//线的类型,实线、虚线等
    //Qt::FlatCap, Qt::SquareCap,Qt::RoundCap
    pen.setCapStyle(Qt::FlatCap);//线端点样式
    //Qt::MiterJoin,Qt::BevelJoin,Qt::RoundJoin,Qt::SvgMiterJoin
    pen.setJoinStyle(Qt::BevelJoin);//线的连接点样式
    painter.setPen(pen);

    painter.setCompositionMode(QPainter::CompositionMode_Difference);

    for(int i=0; i<36;i++)
    {
        painter.drawEllipse(QPoint(50,0),50,50);
        painter.rotate(10);
    }
}

裁剪区域   setClipRegion

延伸:设置widget的背景图片的办法

1.在paintEvent事件中绘制图片

void Widget::paintEvent(QPaintEvent * ev)
{
	QPainter painter(this);
	painter.drawPixmap(rect(),QPixmap(":/bg.jpg"),QRect());
}

缺点就是要使用paintEvent事件需要新建一个类,不适合子窗口

2.使用调色板QPalette来设置图片

QPalette pal =this->palette();
pal.setBrush(QPalette::Background,QBrush(QPixmap(":/bg.jpg")));
setPalette(pal);

3.使用样式表(setStyleSheet)

setStyleSheet("border-image:url(:/bg.jpg)");


项目经验1

1.整个程序的大小通过sizeHint函数设置默认的大小,sizeHint为虚函数,可以重写重新设置大小。

2.框架的widget重写resizeEvent函数(相当于mfc的onsize),调用height、width函数获取到高度、宽度。再通过setGeometry设置画图的区域widget的大小。

3.画图的区域widget重写paintEvent函数。x、y轴都是按比例的画点,画线。(通过画图的区域的高度、宽度。数据的最大值、最小值和实时值。从而按比例算出x,y点坐标。)。

项目经验2

1.直接重写paintEvent函数,默认是视口坐标。即setviewport.  使用的坐标都是固定位置,就算窗口大小变化了,还是固定的。

问题就是有部分图形可能会被遮挡,不会绘图。

项目经验3

直接重写paintEvent函数,但调用setwindow函数使用窗口坐标。这样窗口大小变化时,图形按比例进行缩放。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

qt 绘图QPainter 的相关文章

随机推荐

  • android图片点击全屏显示,Android浏览图片,点击放大至全屏效果

    近期做一个项目类似于QQ空间 做到照片浏览的功能 对于QQ空间中点击图片放大至全屏 感觉效果非常赞 于是也做了个类似的效果 例如以下 我不知道QQ那个是怎么做的 我的思路例如以下 首先 从图片缩略界面跳转到图片详情页面 应该是从一个Acti
  • 概率论在实际生活的例子_概率论学习笔记

    一 从古典概型开始引入概率论的基本概念 古典概型 全称古典概率模型 也叫等可能模型 是人们最早研究的概率 也是学习概率论的起点 古典概型通过随机实验获得结果 而古典概率研究的问题有两个重要特点 结果有限 可能性一致 1 结果有限 指的是实验
  • C语言以字符形式读写文件

    一 字符读取函数 fgetc 一 函数介绍 fgetc 是 file get char 的缩写 意思是从指定的文件中读取一个字符 函数原型为 int fgetc FILE fp fp 为文件指针 fgetc 读取成功时返回读取到的字符 读取
  • Maven快速搭建GUI项目

    一 eclipse安装好maven插件 并将maven集成到eclipse之后 用maven的archetype 搭建好一个maven archetype queckstart项目的骨架 二 可执行jar文件分为两种 一种是可通过命令行ja
  • 【R语言】实验四 数据分析

    系列文章目录 实验一 R 语言数据结构 数据导入与数据处理 实验二 基本数据处理 实验三 数据可视化 实验四 数据分析 实验五 综合应用 实验数据 实验数据下载 1 hospital data 数据集 数据是关于一些医院的基础信息 数据包含
  • 如何降低APP卸载率?这里有七个方法

    如何降低APP卸载率 这里有七个方法 A A admin 2017 年 1 月 19 日 0 597 次浏览 业内资讯 APP卸载率 现在移动应用市场红海一片 获取用户越来越难 但据了解 更让开发者们为难的是 产品的高卸载率 高卸载率是用户
  • Spring事务及事务失效的部分场景

    简介 spring 有五个事务隔离级别 ISOLATION DEFAULT ISOLATION READ UNCOMMITTED ISOLATION READ COMMITTED ISOLATION REPEATABLE READ ISOL
  • 毕业设计 单片机农业土壤酸度检测系统

    文章目录 0 前言 1 简介 2 主要器件 3 实现效果 4 硬件设计 土壤酸碱度传感器 土壤pH传感器与Arduino的硬件连接 5 软件说明 土壤pH传感器的Arduino代码 6 最后 0 前言 这两年开始毕业设计和毕业答辩的要求和难
  • Javascript--位运算符

    文章转载自 http www cnblogs com oneword archive 2009 12 23 1631039 html 1 NOT 位运算符NOT由 表示 NOT运算符的实质是对数字求负 然后减1 位运算符NOT是三步的处理过
  • LeetCode(力扣)455. 分发饼干Python

    LeetCode20 有效的括号 题目链接 代码 题目链接 https leetcode cn problems assign cookies 代码 从大遍历 class Solution def findContentChildren s
  • 华为/荣耀 Magicbook/Matebook 开机经常弹出华为智能还原

    问题描述 今年开始 笔者的Magicbook开机时就会弹出华为智能还原 如下所示 检测之后显示是正常的 于是每次都点退出 退出之后就进入了正常的Win10桌面 但是发现 笔记本电脑存在以下问题 有线网络无法连接 网络里面只有无线WiFi可以
  • Nginx教程:配置TCP/IP转发

    安装nginx服务 检查是否编译时带with stream参数 nginx V grep with stream 有with stream参数 可以代理tcp协议 配置nginx的tcp代理 请注意 stream块和http块是两个不同的模
  • python和易语言的脚本哪门更实用?

    前言 每天我们都会面临许多需要高级的编程挑战 你不能用简单的 Python 基本语法来解决这些问题 在本文中 我将分享 13 个高级 Python 它们可以成为你项目中的便捷工具 如果你目前还用不到这些脚本 你可以先添加收藏 以备留用 文末
  • 使用cesium给地图实例添加精灵图图标

    前置条件 1 将精灵图存放在本地文件中 2 拿到对应的声明文件 该文件中存放了每一个类型的地图实例对应的图标在精灵图中的位置 我这里是json文件 这是某一个实例模型对应的数据 我的做法是 系统登录之后 就掉接口获取到该json文件 并存储
  • 云安全技术——Snort安装与配置

    目录 一 Snort简介 二 安装Centos7 Minimal系统 三 基本环境配置 四 安装Snort 五 下载规则 六 配置Snort 七 测试Snort 一 Snort简介 Snort是一个开源的网络入侵检测系统 主要用于监控网络数
  • 二叉排序树的基本操作

    二叉排序树的应用 利用二叉链表存储二叉排序树 输入一组任意序列 实现二叉排序树的创建 插入 删除 中序遍历 要求 有菜单进行选择 安排 2020 6 4 晴朗 二叉排序树的基本定义 1 左子树的所有节点小于根节点 2 若右子树非空 则右子树
  • NANDFlash-W25N01GVZEIG的学习笔记

    文章目录 一 NAND Flash和NOR Flash 二 W25N01GVZEIG引脚说明 三 SPI配置 四 W25N01GVZEIG的架构和寻址 五 W25N01GVZEIG的指令码 六 W25N01GVZEIG各个指令的解析 一 D
  • PCA 解决 多重共线性问题

    PCA 解决 多重共线性问题 学习链接 link 多重共线性是指自变量彼此相关的一种情况 当你拟合模型并解释结果时 多重共线性可能会导致问题 数据集的变量应该是相互独立的 以避免出现多重共线性问题 线性回归中 多重共线性识别 计算每一个自变
  • mac 版 Nginx 的使用及 web 项目的实际部署--最简单的方式

    1 电脑是否已经安装了 brew 1 1 终端输入指令 which brew 如果显示如下图 则证明已安装 如果未安装 终端执行如下指令 bin bash c curl fsSL https raw githubusercontent co
  • qt 绘图QPainter

    QPainter绘图系统 QPainter用来进行绘图操作的类 绘图设备一般包括Qwidget Qpixmap QImage 他们提供给QPainter画布 QPaintDevice是一个可以使用QPainter进行绘图的抽象二维界面 QP