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