天天看點

Qt擷取滑鼠位置(絕對位置、相對位置)

在進行界面程式設計時,經常需要擷取滑鼠的位置,特别是需要知道滑鼠在界面上某個控件的相對位置。在Qt其實擷取這幾種位置還是比較簡單的。首先我們需要了解Qt的坐标系統,Qt的坐标系統是有QPainter類控制的,而QPainter是在繪圖裝置上繪制。而有時我們并不需要進行繪圖隻需要通過滑鼠事件擷取坐标位置而已,這時我們需要了解兩點:坐标系統和控件的層次關系。首先預設坐标系統中原點(0,0)在其左上角,x坐标向右增長,y坐标向下增長。在基于像素的裝置上,預設的機關是一個像素,而在列印機上預設的機關是一個點(1/72英寸)。控件的層次關系是根據控件在界面中的布局位置決定的,如下:leftImgLabel的位置就相對于centralWidget而言,通過leftImgLabel.pos()擷取的位置并不是全局位置而是相對于centralWidget的位置。

Qt擷取滑鼠位置(絕對位置、相對位置)

如果通過leftImgLabel來顯示圖檔,通過滑鼠來擷取圖檔中某個點的位置,如果直接使用滑鼠事件中的event->pos()擷取的位置并不對應你實際标注的圖像上的點,而是滑鼠相對于目前視窗的位置(event->globalPos()擷取的滑鼠相對于目前顯示器的位置,可以采用任意截圖工具進行測試)。這時就需要将滑鼠坐标根據控件的層次關系去轉換。

Qt擷取滑鼠位置(絕對位置、相對位置)

上圖中紅色方框右下角的坐标: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顯示的圖檔如下:

Qt擷取滑鼠位置(絕對位置、相對位置)

此時圖檔并沒有填充滿整個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.注意填充内容相對于控件本身的位移