博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
QPainter 中的setWindow与setViewPort
阅读量:3986 次
发布时间:2019-05-24

本文共 3117 字,大约阅读时间需要 10 分钟。

转自:

近段时间一直研究,QPainter绘图以及使用QPainter绘制动画;直到今天看到一篇博客中使用QPainter绘图之后,

仅仅只是在绘图前使用了一个setWindow函数就能让图形自适应;于是做了研究。

首先我们不启动以上两个函数,添加如下代码

    QPainter painter(this);

    painter.setRenderHint(QPainter::Antialiasing);
    painter.setPen(QPen(Qt::black, 2, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
//    painter.setWindow(0,0,300,200); //painter的逻辑绘图区域,左上角为(0,2),右下角为(300,200)
//    painter.setViewport(0,-height() + _y,width(),height()); //实际在窗口映射到窗口显示的区域
 
    QLinearGradient linGrad1(20, 100, 40, 100);
    linGrad1.setColorAt(0, Qt::gray);
    linGrad1.setColorAt(1, Qt::white);
    linGrad1.setSpread(QGradient::ReflectSpread);
    painter.setBrush(linGrad1);
 
    QRectF border1(20, 20, 260, 160);
    painter.drawRoundRect(border1, 20, 20);
 
    painter.setPen(QPen(Qt::black, 1, Qt::DotLine, Qt::RoundCap, Qt::RoundJoin));
    QRectF border2(25, 25, 250, 150);
    painter.drawRoundRect(border2, 20, 20);
得到的结束如下

如果我们将窗口放大,可以发现图形位置没有变,大小也没有变

修改代码在绘制之前设置painter的逻辑绘图坐标window

    QPainter painter(this);

    painter.setRenderHint(QPainter::Antialiasing);
    painter.setPen(QPen(Qt::black, 2, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
    painter.setWindow(0,0,300,200); //painter的逻辑绘图区域,左上角为(0,2),右下角为(300,200)
//    painter.setViewport(0,-height() + _y,width(),height()); //实际在窗口映射到窗口显示的区域
 
    QLinearGradient linGrad1(20, 100, 40, 100);
    linGrad1.setColorAt(0, Qt::gray);
    linGrad1.setColorAt(1, Qt::white);
    linGrad1.setSpread(QGradient::ReflectSpread);
    painter.setBrush(linGrad1);
 
    QRectF border1(20, 20, 260, 160);
    painter.drawRoundRect(border1, 20, 20);
 
    painter.setPen(QPen(Qt::black, 1, Qt::DotLine, Qt::RoundCap, Qt::RoundJoin));
    QRectF border2(25, 25, 250, 150);
    painter.drawRoundRect(border2, 20, 20);

将窗口放大后,可以看见图形在保持比例缩放,就像layOut一样

再修改代码,为painter添加视图区域

    QPainter painter(this);

    painter.setRenderHint(QPainter::Antialiasing);
    painter.setPen(QPen(Qt::black, 2, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
    painter.setWindow(0,0,300,200); //painter的逻辑绘图区域,左上角为(0,2),右下角为(300,200)
    painter.setViewport(100,50,100,100); //实际在窗口映射到窗口显示的区域
 
    QLinearGradient linGrad1(20, 100, 40, 100);
    linGrad1.setColorAt(0, Qt::gray);
    linGrad1.setColorAt(1, Qt::white);
    linGrad1.setSpread(QGradient::ReflectSpread);
    painter.setBrush(linGrad1);
 
    QRectF border1(20, 20, 260, 160);
    painter.drawRoundRect(border1, 20, 20);
 
    painter.setPen(QPen(Qt::black, 1, Qt::DotLine, Qt::RoundCap, Qt::RoundJoin));
    QRectF border2(25, 25, 250, 150);
    painter.drawRoundRect(border2, 20, 20);

图形显示在(100,50,100,100)的区域

我们放大窗口

可以发现显示的位置始终在(100,50,100,100)的区域,这所以没有设置时图形能够根具窗口大小自适应,查看文档可知,默认painter的viewPort是与窗口尺寸

相等的;所以这样将逻辑坐标的内容每次都映射到当前窗口就能保证图形自适应了。

查看官方文档可知,painter的默认逻辑区域也是整个窗口区域;这样当我们不去改变逻辑绘图区域和视口时,他们的区域都是窗口区域,这样就形成了我们

常见的画在窗口中的哪个位置就在那个位置显示。而今天的总结,我们可以清楚;其实QPainter画图用的是逻辑坐标(就是自定义左上角坐标和右下角坐标),且

绘图操作都是以逻辑坐标为基准的,当绘图线束后,根据视口区域在窗口中的位置,再把整个绘画结果通过坐标映射全部映射到视口区域(也可以理解为映射因子为逻辑区域

到视口区域的映射转换);注意这里是将整个绘图结果映射,比如绘图时,图形有一部分画在了逻辑区域之外,但通过映射后,如果视口区域名够大能够包映射后的整个图形,

依然是可以显示的,但逻辑区域左上角和右下角映射后的位置一定是视口区域的左上角和右下角

由此,我们在绘制自适应部件时,就方便了,在绘制前设置逻辑坐标区域(固定区域,不要随窗口变化)就可以了,我们在这个固定的逻辑绘图区域先把图画好,再将图

映射到整个窗口(因为默认视口是整个窗口)。窗口尺寸变化时,会自动重绘。

--------------------- 
作者:程序开发人生 
来源:CSDN 
原文:https://blog.csdn.net/wanghualin033/article/details/78752666 
版权声明:本文为博主原创文章,转载请附上博文链接!

你可能感兴趣的文章
coursesa课程 Python 3 programming Accumulating Multiple Results In a Dictionary 统计文件的字母数量
查看>>
Returning a value from a function
查看>>
coursesa课程 Python 3 programming Functions can call other functions 函数调用另一个函数
查看>>
coursesa课程 Python 3 programming Tuple Assignment with Unpacking
查看>>
coursesa课程 Python 3 programming The while Statement
查看>>
course_2_assessment_6
查看>>
coursesa课程 Python 3 programming course_2_assessment_7 多参数函数练习题
查看>>
coursesa课程 Python 3 programming 排序函数sorted的可选参数
查看>>
coursesa课程 Python 3 programming course_2_assessment_8 sorted练习题
查看>>
visca接口转RS-232C接口线序
查看>>
在unity中建立最小的shader(Minimal Shader)
查看>>
RGB 立方体
查看>>
1.3 Debugging of Shaders (调试着色器)
查看>>
关于phpcms中模块_tag.class.php中的pc_tag()方法的含义
查看>>
vsftp 配置具有匿名登录也有系统用户登录,系统用户有管理权限,匿名只有下载权限。
查看>>
linux安装usb wifi接收器
查看>>
关于共享单车定位不准问题
查看>>
ubuntu误删文件造成软件包信息列表损坏无法更新或安装文件
查看>>
终于搞定CString和string之间转换的问题了
查看>>
用防火墙自动拦截攻击IP
查看>>