1. 程式人生 > >Qt檢視場景框架之一些“坑”

Qt檢視場景框架之一些“坑”

        這裡所謂“坑”也不一定是Qt的bug,主要還是幫助文件不好理解或啃的不夠透徹導致,總結一下以免重蹈覆轍繞彎路。

       1、   Qt中事件傳遞是由父向子傳遞,同樣在檢視場景中事件傳遞是View->Scene->Item這樣的順序,所以上層的事件函式重寫必須呼叫父類事件函式,實現事件的向下傳遞,不至於阻塞後面元素的事件處理。

       2、   在View中呼叫setBackgroundBrush方法會阻止Scene中drawBackground方法的呼叫,這個幫助中有說明,屬於幫助看的不仔細。另外View/Scene中的drawBackground和drawForeground方法類似事件函式,呼叫順序是View->Scene,所以在自定義View中drawBackground和drawForeground方法時需要呼叫父類方法。

      3、   QGraphicsScene::sceneRect和QGraphicsView::sceneRect是有區別的,QGraphicsScene::sceneRect是場景的實際範圍大小,是一個抽象邏輯概念,例如用場景作為畫布,為畫布的實際大小。QGraphicsView::sceneRect則是在View中需要給Scene預留的區域大小,這個類似視窗概念,QGraphicsView::sceneRect的大小直接影響則View視窗中滾動條的出現。在開發中QGraphicsScene::sceneRect最好小於等於QGraphicsView::sceneRect大小,以保證在縮放View時通過滾動條可以檢視到完整的Scene區域。

     4、   QGraphicsItemGroup的位置問題,建立的group在場景中的初始pos()始終為(0,0),這一點與普通item不同。不知道Qt對QGraphicsItemGroup這樣設計的原因是什麼,把它理解成普通item確實帶來不少問題,感覺是個“坑”。一般item的pos()就是item的sceneBoundingRect的左上角,所以為了統一我們也可以對group取sceneBoundingRect().topLeft()作為它的pos。對group setPos時先計算新pos與topLeft點的offset,然後通過group.setPos(group.pos()+offset)來實現group新位置移動。

     5、   給Item設定新的位置,在對item進行了一些列複雜的transform變換或其他操作後,有時候會出現setPos時位置與預想的不一致,多半是item相對Scene的座標系對映關係發生了我們未察覺的變化導致的。這個時候你再對item setPos到Scene中具體的某個點時會出現偏差,我遇見類似問題的一個思路是,不要使用setPos設定絕對的位置點,而是先求取原pos與要設定pos的offset,然後同4中那樣通過item.setPos(item.pos()+offset)來實現item新位置設定,一般可以達到預期的位置。