詳解 Qt 2D繪圖之Qt坐標系統深入
Qt 2D繪圖之Qt坐標系統深入是本文要介紹的內容,了解了 Qt 坐標系統的概念,通過對幾個函數的應用,應該已經對Qt的坐標系統有了一個模糊的認識。那么現在就來讓我們更深入地研究一下Qt窗口的坐標。希望大家把這一節的例子親手做一下,不要被筆者所說的東西搞暈了!
我們還是在以前的工程中進行操作。
獲得坐標信息:
為了更清楚地獲得坐標信息,我們這里利用鼠標事件,讓鼠標點擊左鍵時輸出該點的坐標信息。
1、在工程中的dialog.h文件中添加代碼。
添加頭文件: #include <QMouseEvent>
在public中添加函數聲明:void mousePressEvent(QMouseEvent *);
然后到dialog.cpp文件中:
添加頭文件: #include <QDebug>
定義函數:
- void Dialog::mousePressEvent(QMouseEvent *event)
- {
- qDebug() << event->pos();
- }
這里應用了qDebug()函數,利用該函數可以在程序運行時將程序中的一些信息輸出,在Qt Creator中會將信息輸出到其下面的Application Output窗口。這個函數很有用,在進行簡單的程序調試時,都是利用該函數進行的。我們這里利用它將鼠標指針的坐標值輸出出來。
2、然后更改重繪事件函數。
- void Dialog::paintEvent(QPaintEvent *)
- {
- QPainter painter(this);
- painter.drawRect(0,0,50,50);
- }
我們繪制了一個左上頂點為(0,0),寬和高都是50的矩形。
3、這時運行程序。并在繪制的矩形左上頂點點擊一下鼠標左鍵。效果如下。(點擊可看大圖)
因為鼠標點的不夠準確,所以輸出的是(1,0),我們可以認為左上角就是原點(0,0)點。你可以再點擊一下矩形的右下角,它的坐標應該是(50,50)。這個方法掌握了以后,我們就開始研究這些坐標了。
#p#
研究放大后的坐標
1、我們現在進行放大操作,然后查看其坐標的變化。
- void Dialog::paintEvent(QPaintEvent *)
- {
- QPainter painter(this);
- painter.scale(2,2); //橫縱坐標都擴大2倍
- painter.drawRect(0,0,50,50);
- }
我們將橫縱坐標都擴大2倍,然后運行程序,查看效果:
我們點擊矩形右下頂點,是(100,100),比以前的(50,50)擴大了2倍。
研究QPixmap或QImage的坐標
對于QWidget,QPixmap或QImage等都是繪圖設備,我們都可以在其上利用QPainter進行繪圖。現在我們研究一下QPixmap的坐標(QImage與其效果相同)。
1、我們更改重繪事件函數如下。
- void Dialog::paintEvent(QPaintEvent *)
- {
- QPainter painter(this);
- QPixmap pix(200,200);
- pix.fill(Qt::red); //背景填充為紅色
- painter.drawPixmap(0,0,pix);
- }
這里新建了一個寬、高都是200像素的QPixmap類對象,并將其背景顏色設置為紅色,然后從窗口的原點(0,0)點添加該QPixmap類對象。為了表述方便,在下面我們將這個QPixmap類對象pix稱為畫布。
我們運行程序,并在畫布的左上角和右下角分別點擊一下,效果如下:
可以看到其左上角為(0,0)點,右下角為(200,200)點,是沒有問題的。
#p#
2、我們再將函數更改如下。
- void Dialog::paintEvent(QPaintEvent *)
- {
- QPainter painter(this);
- QPixmap pix(200,200);
- pix.fill(Qt::red); //背景填充為紅色
- painter.drawPixmap(100,100,pix);
- }
這時我們從窗口的(100,100)點添加該畫布,那么此時我們再點擊畫布的右上角,其坐標會是多少呢?
可以看到,它是(100,100),沒錯,這是窗口上的坐標,那么這是不是畫布上的坐標呢?
3、我們接著更改函數。
- void Dialog::paintEvent(QPaintEvent *)
- {
- QPainter painter(this);
- QPixmap pix(200,200);
- pix.fill(Qt::red); //背景填充為紅色
- QPainter pp(&pix); //新建QPainter類對象,在pix上進行繪圖
- pp.drawLine(0,0,50,50); //在pix上的(0,0)點和(50,50)點之間繪制直線
- painter.drawPixmap(100,100,pix);
- }
這里我們又新建了一個QPainter類對象pp,其中pp(&pix)表明,pp所進行的繪圖都是在畫布pix上進行的。
現在先說明一下:
QPainter painter(this) ,this就表明了是在窗口上進行繪圖,所以利用painter進行的繪圖都是在窗口上的,painter進行的坐標變化,是變化的窗口的坐標系;而利用pp進行的繪圖都是在畫布上進行的,如果它進行坐標變化,就是變化的畫布的坐標系。
我們在畫布上的(0,0)點和(50,50)點之間繪制了一條直線。這時運行程序,點擊這條直線的兩端,看看其坐標值。
#p#
結果是直線的兩端的坐標分別是(100,100),(150,150)。我們從中可以得出這樣的結論:
第一,QWidget和QPixmap各有一套坐標系統,它們互不影響。可以看到,無論畫布在窗口的什么位置,它的坐標原點依然在左上角,為(0,0)點,沒有變。
第二,我們所得到的鼠標指針的坐標值是窗口提供的,不是畫布的坐標。
下面我們繼續研究:
4、比較下面兩個例子。
例子一:
- void Dialog::paintEvent(QPaintEvent *)
- {
- QPainter painter(this);
- QPixmap pix(200,200);
- qDebug() << pix.size(); //放大前輸出pix的大小
- pix.fill(Qt::red);
- QPainter pp(&pix);
- pp.scale(2,2); //pix的坐標擴大2倍
- pp.drawLine(0,0,50,50); //在pix上的(0,0)點和(50,50)點之間繪制直線
- qDebug() << pix.size(); //放大后輸出pix的大小
- painter.drawPixmap(0,0,pix);
- }
例子二:
- void Dialog::paintEvent(QPaintEvent *)
- {
- QPainter painter(this);
- QPixmap pix(200,200);
- qDebug() << pix.size(); //放大前輸出pix的大小
- painter.scale(2,2); //窗口坐標擴大2倍
- pix.fill(Qt::red);
- QPainter pp(&pix);
- pp.drawLine(0,0,50,50); //在pix上的(0,0)點和(50,50)點之間繪制直線
- qDebug() << pix.size(); //放大后輸出pix的大小
- painter.drawPixmap(0,0,pix);
- }
兩個例子中都使直線的長度擴大了兩倍,但是第一個例子是擴大的畫布的坐標系,第二個例子是擴大的窗口的坐標系,你可以看一下它們的效果。
你仔細看一下輸出,兩個例子中畫布的大小都沒有變。
如果你看過了我寫的那個繪圖軟件的教程(鏈接過去),現在你就能明白我在其中講“問題一”時說的意思了:雖然畫布看起來是大了,但是其大小并沒有變,其中坐標也沒有變。變的是像素的大小或者說像素間的距離。
但是,有一點你一定要搞明白,這只是在QPixmap與QWidget結合時才出現的,是相對的說法。其實利用scale()函數是會讓坐標變化的,我們在開始的例子已經證明了。
現在是不是已經很亂了,一會兒是窗口,一會兒是畫布,一會兒坐標變化,一會兒又不變了,到底是怎么樣呢?其實只需記住一句話:所有的繪圖設備都有自己的坐標系統,它們互不影響。(本文章原創于www.yafeilinux.com )
小結:Qt 2D繪圖之Qt坐標系統深入的內容介紹完了,希望本篇文章對你有幫助!