來源:http://apps.hi.baidu.com/share/detail/24642054#content
前面一節(jié)我們講解了圖片的顯示, 其中很多都用到了坐標的變化,這一節(jié)我們簡單講一下Qt的坐標系統(tǒng),其實也還是主要講上一節(jié)的那幾個函數(shù)。這里我們先講解一下Qt的坐標系,然后講解那幾 個函數(shù),它們分別是:
translate()函數(shù),進 行平移變換;scale()函數(shù),進行比例變換;rotate()函數(shù),進行旋轉變換;shear()函數(shù),進行扭曲變換。
最后介紹兩個有用的函數(shù) save()和restore(),利用它們來保存和彈出坐標系的狀態(tài),從而實現(xiàn)快速利用幾個變換來繪圖。
一、坐標系簡 介。
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);
}
我們先在原點(0,0)繪制了一個長寬都是100 像素的紅色矩形,又在(-50,-50)點繪制了一個同樣大小的黃色矩形。可以看到,我們只能看到黃色矩形的一部分。效果如下圖。
二、坐標系變換。
坐標系變換是利用變換矩陣來進行的, 我們可以利用QTransform類來設置變換矩陣,因為一般我們不需要進行更改,所以這里不在涉及。下面我們只是對坐標系的平移,縮放,旋轉,扭曲等應 用進行介紹。
1.利用 translate()函數(shù)進行平移變換。
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()函數(shù)進行比例變換,實現(xiàn)縮放效果。
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),是將橫縱坐標都擴大了兩倍,現(xiàn)在的(50,50)點就相當于以前的
(100,100) 點。
3. 利用shear()函數(shù)就行扭曲變換。
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);
}
效果如下。
這里,painter.shear(0,1),是對縱向進行扭曲,0表示不扭曲,當將第一個0更改時就會對橫行進行扭曲,關于扭曲變換 到底是什么效果,你觀察一下是很容易發(fā)現(xiàn)的。
4.利用rotate()函數(shù)進行比例變換,實現(xiàn)縮放效果。
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);
}
效果如下。
因為默認的rotate()函數(shù)是以原點為中心進行順時針旋轉的,所以我們要想使其以其他點為中心進行旋轉,就要先進行原點的變換。這 里的painter.translate(100,100)將(100,100)設置為新的原點,想讓直線以其為中心進行旋轉,可是你已經發(fā)現(xiàn)效果并非如 此。是什么原因呢?我們添加一條語句,如下:
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);
}
效果如下。
這時就是我們想要的效果了。我們加的一句代碼為painter.rotate(-30),這是因為前面已經將坐標旋轉了30度,我們需 要將其再旋轉回去,才能是以前正常的坐標系統(tǒng)。不光這個函數(shù)如此,這里介紹的這幾個函數(shù)均如此,所以很容易出錯。下面我們將利用兩個函數(shù)來很好的解決這個 問題。
三、坐標系狀態(tài)的保護。
我們可以先利用save()函數(shù)來保存坐標系現(xiàn)在的狀態(tài),然后進行變換操作,操作完之后,再用restore()函數(shù)將以前的坐標系狀 態(tài)恢復,其實就是一個入棧和出棧的操作。
例如:
void Dialog::paintEvent(QPaintEvent *)
{
QPainter painter(this);
painter.save();// 保存坐標系狀態(tài)
painter.translate(100,100);
painter.drawLine(0,0,50,50);
painter.restore();//恢復以前的坐標系狀態(tài)
painter.drawLine(0,0,50,50);
}
效果如下。
利用好這兩個函數(shù),可以實現(xiàn)快速的坐標系切換,繪制出不同的圖形。
聯(lián)系客服