QPainter中坐标系变换问题

一、坐标系简介。

Qt中每一个窗口都有一个坐标系,默认的,窗口左上角为坐标原点,然后水平向右依次增大,水平向左依次减小,垂直向下依次增大,垂直向上依次减小。原点即为(0,0)点,然后以像素为单位增减。

例如:

void Dialog::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);

}


二、坐标系变换。

坐标系变换是利用变换矩阵来进行的,我们可以利用QTransform类来设置变换矩阵,因为一般我们不需要进行更改,所以这里不在涉及。下面我们只是对坐标系的平移,缩放,旋转,扭曲等应用进行介绍。

1.利用translate()函数进行平移变换。

void Dialog::paintEvent(QPaintEvent *)
{
    QPainter painter(this);
    painter.setBrush(Qt::yellow);
    painter.drawRect(0,0,50,50);

   painter.translate(100,100); //将点(100,100)设为原点

    painter.setBrush(Qt::red);
    painter.drawRect(0,0,50,50);

   painter.translate(-100,-100);

    painter.drawLine(0,0,20,20);
}

这里将(100,100)点作为了原点,所以此时(100,100)就是(0,0)点,以前的(0,0)点就是

(-100,-100)点。要想使原来的(0,0)点重新成为原点,就是将(-100,-100)设为原点。


2.利用scale()函数进行比例变换,实现缩放效果。

void Dialog::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);
}

painter.scale(2,2),是将横纵坐标都扩大了两倍,现在的(50,50)点就相当于以前的

(100,100)点。

3.利用shear()函数就行扭曲变换。

void Dialog::paintEvent(QPaintEvent *)
{
    QPainter painter(this);
    painter.setBrush(Qt::yellow);
    painter.drawRect(0,0,50,50);

    painter.shear(0,1); //纵向扭曲变形
    painter.setBrush(Qt::red);
    painter.drawRect(50,0,50,50);
}
效果如下。


4.利用rotate()函数进行比例变换,实现缩放效果。

void Dialog::paintEvent(QPaintEvent *)
{
    QPainter painter(this);
    painter.drawLine(0,0,100,0);

    painter.rotate(30); //以原点为中心,顺时针旋转30度
    painter.drawLine(0,0,100,0);

   painter.translate(100,100);
    painter.rotate(30);
    painter.drawLine(0,0,100,0);
}


void Dialog::paintEvent(QPaintEvent *)
{
    QPainter painter(this);
    painter.drawLine(0,0,100,0);

    painter.rotate(30); //以原点为中心,顺时针旋转30度
    painter.drawLine(0,0,100,0);

   painter.rotate(-30);

    painter.translate(100,100);
    painter.rotate(30);
    painter.drawLine(0,0,100,0);
}

三、坐标系状态的保护。

我们可以先利用save()函数来保存坐标系现在的状态,然后进行变换操作,操作完之后,再用restore()函数将以前的坐标系状态恢复,其实就是一个入栈和出栈的操作。

例如:

void Dialog::paintEvent(QPaintEvent *)
{
    QPainter painter(this);
    painter.save(); //保存坐标系状态
    painter.translate(100,100);
    painter.drawLine(0,0,50,50);

    painter.restore(); //恢复以前的坐标系状态
    painter.drawLine(0,0,50,50);
}
效果如下。










你可能感兴趣的:(QT)