00. 目录
01. 概述
Qt中每一个窗口都有一个坐标系统,默认的,窗口左上角为坐标原点,水平向右依次增大,水平向左依次减小,垂直向下依次增大,垂直向上依次减小。原点即为(0,0)点,以像素为单位增减。
02. 开发环境
Windows系统:Windows10
Qt版本:Qt5.15或者Qt6
03. Qt坐标系统
程序示例
void Widget::paintEvent(QPaintEvent *)
{
QPainter painter(this);
painter.setBrush(Qt::red);
painter.drawRect(0, 0, 100, 100);
painter.setBrush(Qt::yellow);
painter.drawRect(-50, -50, 100, 100);
}
执行结果
04. 坐标系统变换
默认的,QPainter在指定设备的坐标系统上进行绘制,在进行绘图时,可以使用QPainter::scale()函数缩放坐标系统;使用QPainter::rotate()函数顺时针旋转坐标系统;使用QPainter::translate()函数平移坐标系统;还可以使用QPainter::shear()围绕原点来扭曲坐标系统。如下图所示。
坐标系统的2D变换由QTransform类实现,我们可以使用前面提到的那些便捷函数进行坐标系统变换,当然也可以通过QTransform类实现。
05. 平移变换
程序示例
//平移变换
void Widget::paintEvent(QPaintEvent *)
{
QPainter painter(this);
painter.setBrush(Qt::yellow);
painter.drawRect(0, 0, 50, 50);
//相当于将(100,100)设为原点
painter.translate(100, 100);
painter.setBrush(Qt::red);
painter.drawRect(0, 0, 50, 50);
//相当于在原来原点的基础之上减去(100, 100)当做新的原点
painter.translate(-100, -100);
painter.drawLine(0, 0, 20, 20);
}
执行结果
这里先在原点(0, 0)绘制了一个宽、高均为50的正方形,然后使用translate()函数将坐标系统进行了平移,使(100, 100)点成为了新原点,所以我们再次进行绘制的时候,虽然drawRect()中的逻辑坐标还是(0, 0)点,但实际显示出来的却是在(100, 100)点的红色正方形。可以再次使用translate()函数进行反向平移,使原点重新回到窗口左上角。
06. 缩放变换
程序示例
//缩放变换
void Widget::paintEvent(QPaintEvent *)
{
QPainter painter(this);
painter.setBrush(Qt::yellow);
painter.drawRect(0, 0, 100, 100);
//放大两倍
painter.scale(2, 2);
painter.setBrush(Qt::red);
painter.drawRect(50, 50, 50, 50);
}
执行结果
可以看到,当我们使用scale()函数将坐标系统的横、纵坐标都放大两倍以后,逻辑上的(50, 50)点变成了窗口上的(100, 100)点,而逻辑上的长度50,绘制到窗口上的长度却是100。
07. 扭曲变换
程序示例
//扭曲变换
void Widget::paintEvent(QPaintEvent *)
{
QPainter painter(this);
painter.setBrush(Qt::yellow);
painter.drawRect(0, 0, 50, 50);
//纵向扭曲变换
painter.shear(0, 1);
painter.setBrush(Qt::blue);
painter.drawRect(50, 0, 50, 50);
}
执行结果
shear()有两个参数,第一个是对横向进行扭曲,第二个是对纵向进行扭曲,而取值就是扭曲的程度。比如程序中对纵向扭曲值为1,那么就是红色正方形左边的边下移一个单位,右边的边下移两个单位,值为1就表明右边的边比左边的边多下移一个单位。大家可以更改取值,测试效果。
08. 旋转变换
程序示例
//旋转变换
void Widget::paintEvent(QPaintEvent *)
{
QPainter painter(this);
painter.drawLine(0, 0, 100, 0);
//以原点为中心 顺时针旋转30°
painter.rotate(30);
painter.drawLine(0, 0, 100, 0);
painter.translate(100, 100);
painter.rotate(30);
painter.drawLine(0, 0, 100, 0);
}
执行结果
程序示例二:
//旋转变换
void Widget::paintEvent(QPaintEvent *)
{
QPainter painter(this);
painter.drawLine(0, 0, 100, 0);
//以原点为中心 顺时针旋转30°
painter.rotate(30);
painter.drawLine(0, 0, 100, 0);
//反向旋转
painter.rotate(-30);
painter.translate(100, 100);
painter.drawLine(0, 0, 100, 0);
painter.rotate(30);
painter.drawLine(0, 0, 100, 0);
}
执行结果:
这次我们在移动原点以前先将坐标系统反向旋转,可以看到,第二次旋转也是从水平方向开始的。
其实,前面讲到的这几个变换函数都是如此,他们改变了坐标系统以后,如果不进行逆向操作,坐标系统是无法自动复原
09. 附录
源码下载:【Qt】2D绘图之坐标系统.rar
暂无评论内容