在進行界面編程時,經常需要獲取鼠標的位置,特別是需要知道鼠標在界面上某個控件的相對位置。在Qt其實獲取這幾種位置還是比較簡單的。首先我們需要了解Qt的座標系統,Qt的座標系統是有QPainter類控制的,而QPainter是在繪圖設備上繪製。而有時我們並不需要進行繪圖只需要通過鼠標事件獲取座標位置而已,這時我們需要了解兩點:座標系統和控件的層次關係。首先默認座標系統中原點(0,0)在其左上角,x座標向右增長,y座標向下增長。在基於像素的設備上,默認的單位是一個像素,而在打印機上默認的單位是一個點(1/72英寸)。控件的層次關係是根據控件在界面中的佈局位置決定的,如下:leftImgLabel的位置就相對於centralWidget而言,通過leftImgLabel.pos()獲取的位置並不是全局位置而是相對於centralWidget的位置。
如果通過leftImgLabel來顯示圖片,通過鼠標來獲取圖片中某個點的位置,如果直接使用鼠標事件中的event->pos()獲取的位置並不對應你實際標註的圖像上的點,而是鼠標相對於當前窗口的位置(event->globalPos()獲取的鼠標相對於當前顯示器的位置,可以採用任意截圖工具進行測試)。這時就需要將鼠標座標根據控件的層次關係去轉換。
上圖中紅色方框右下角的座標:event->pos():QPoint(269,287),event->globalPos: QPoint(763,549)而真實對應的圖片中的座標則是pos()-(centralWidget.pos()+leftImgLabel.pos())(窗口座標減去父窗口座標和當前窗口座標).
其實在Qt中有比較簡單的方式去獲取QLabel上內容的座標:
leftButtomRightPoint = event->globalPos(); //獲取全局位置
leftButtomRightPoint = ui->leftImgLabel->mapFromGlobal(leftButtomRightPoint);首先鼠標獲取全局座標,然後通過QLabel封裝的mapFromGlobal函數進行轉換。注意這時獲取的座標都還只是QLabel中的位置(相對於QLabel的座標原點而言)!但是由於QLabel的具體範圍和QLbael上顯示的內容位置並不一致,如果QLabel顯示的圖片如下:
此時圖片並沒有填充滿整個QLabel的空間,只是佔用其中一部分內容,這時就需要知道圖像在QLabel中的具體位置了。當圖像不能填充滿整個QLabel空間時,需要在QLabel的顯示屬性設置對齊方式,這時推薦採用居中對齊(方便後續處理,其他對齊方式計算可能不方便)
設置QLabel的對齊方式採用:
ui->leftImgLabel->setAlignment(Qt::AlignCenter); //居中顯示設置好顯示方式後,就可以知道圖像在QLabel中的位置啦(正中間),然後就可以計算圖像相對於QLabel的偏移量啦,計算方式如下:
//QLabel內容相對於QLbael本身的偏移量
xoffset = (ui->leftImgLabel->contentsRect().width()-ui->leftImgLabel->pixmap()->rect().width())/2;
yoffset = (ui->leftImgLabel->contentsRect().height()-ui->leftImgLabel->pixmap()->rect().height())/2;
contentsRect表示的是QLabel的內容範圍,而pixmap->rect()則表示的圖像的實際大小,通過這樣的處理就可以得出圖像相對於QLabel的具體偏移量,然後這時就可以真正將鼠標座標轉換成圖像上的點位置了:
topPoint.x = leftTopLeftPoint.x()-xoffset;
topPoint.y = leftTopLeftPoint.y()-yoffset;
buttomPoint.x = leftButtomRightPoint.x()-xoffset;
buttomPoint.y = leftButtomRightPoint.y()-yoffset;通過這樣的轉換終於可以將鼠標選取的點轉爲我們想要的座標(相對座標).
總結:
1.注意控件的層次關係
2.注意填充內容相對於控件本身的位移