2015-10-08 109 views
0

我有一個奇怪的問題,我一直無法確定原因。基本上,我創建了具有平移和縮放功能的2D視圖以及可以通過網格對齊移動的項目。要移動場景中的項目,我擴展了Scene::mousePressEvent以獲取指向該項目的指針,並且使Scene::mouseMoveEvent獲得指示器以跟蹤光標上的項目。要刪除該項目,我再次使用了Scene::mousePressEvent。爲了平移,我擴展了View::mousePressEvent,View::mouseReleaseEventView::mouseMoveEvent並將I擴展爲View::wheelEventQGraphicsScene mouseMoveEvent不工作,直到QGraphicsView wheelEvent

現在的症狀:

我開始與場景中的項目的應用程序。如果我點擊並按住,然後移動鼠標,該項目將按預期移動。只要我釋放鼠標按鈕,該項目停止移動。我可以點擊放下,並根據Scene::mousePressEvent中的下拉代碼放置該項目。再試一次,只有當鼠標按鈕被按下時,項目纔會移動。

然後出現奇怪的部分:如果我使用鼠標滾輪縮放視圖,那麼在該事件發生後,所有事情都按預期執行。點擊鼠標來選擇一個項目,它隨着我移動鼠標而移動,當我再次點擊時,它會掉落。

那麼顯而易見的解決方案:

wheelEvent(new QWheelEvent(QPointF(0,0),0,Qt::NoButton,Qt::NoModifier)); 

稱爲在創建視圖,一切工作正常。它調用擴展的View::wheelEvent而不改變視圖,甚至在創建場景之前,但之後程序的行爲如預期。

所以我在這裏看看有沒有優秀的Qt專家能解釋這種奇怪的行爲。任何意見或方向表示讚賞。

如果有幫助,這裏是View::wheelEvent覆蓋代碼。 tform是與我保持縮放的QTransform。另外,我嘗試過和沒有調用基本方法,但行爲沒有變化。

void SchematicView::wheelEvent(QWheelEvent* event) 
{ 
    // Scale the view/do the zoom 
    double scaleFactor = 1.1; 

    if(event->delta() > 0 && tform.m11() < max_zoom) { 
     tform.scale(scaleFactor,scaleFactor); 
    } else if (event->delta() < 0 && tform.m11() > min_zoom){ 
     tform.scale(1.0/scaleFactor,1.0/scaleFactor); 
    } 

    setTransformationAnchor(QGraphicsView::AnchorUnderMouse); 
    setTransform(tform); 

    QGraphicsView::wheelEvent(event); 

} 
+0

請注意,您的顯而易見的解決方案被泄露QWheelEvent對象......你會更好放置QWheelEvent對象在棧上,或wheelEvent()返回後,至少將其刪除。 –

回答

2

沒有一個SSCCE來看待和測試用,很難肯定地說,但什麼你描述聽起來很像你mouseMoveEvent()回調纔剛剛調用的時候,鼠標按鈕在移動過程中被按住。如果 鼠標按鈕,而鼠標按下

如果鼠標跟蹤已關閉,鼠標移動事件只發生:那反過來,聽起來很像的mouseMoveEvent(預期的行爲),如記錄在QWidget::mouseMoveEvent()正在移動。如果開啓了跟蹤功能,鼠標移動事件即使沒有按下鼠標按鈕,也會發生。

如果確實是這個問題,那麼致電setMouseTracking(true)可能會得到您正在查找的行爲。

在更廣泛的層面上,請注意,有更簡單的方法可以獲得您嘗試實施的行爲 - 例如,允許用戶在QGraphicsScene中拖放項目,您只需調用setFlags(QGraphicsItem :: ItemIsMovable)在您希望用戶能夠拖動的任何QGraphicsItems上。除非您試圖獲取一些非標準行爲,否則不需要手動編寫事件處理程序。

+0

我認爲你正在使用setMouseTracking(true)。我明天會嘗試。至於場景編碼,我需要捕捉到網格,所以我必須處理pressEvent。我很欣賞ItemIsMovable上的建議,但我創建了自己的Item類,它們表示不同的形狀和像素圖,並且由於我必須重寫虛擬繪畫事件,所以我沒有注意到這些標誌做任何事情。如果您有任何關於使用自定義Item類的建議以及可以捕捉到網格的默認可移動行爲,我很樂意聽到它。沒有理由重新發明輪子。沒有雙關語意。 – Johnny

+0

我相信可以使用標準的item-move功能來處理自定義的QGraphicsItem子類(我自己沒有嘗試過,但如果它不可能,我會感到驚訝)。至於snap-to-grid,我認爲實現這個的方法是重寫QGraphicsItem子類中的itemChange(GraphicsItemChange變化,const QVariant&value)方法,並且在(change)等於ItemPositionChange的情況下返回snapped該項目的網格位置。 (請參閱此處的說明:http://doc.qt.io/qt-4.8/qgraphicsitem.html#GraphicsItemChange-enum) –

+0

感謝您解決鼠標跟蹤問題。因爲在進入這裏之前搜索了文檔,並且不理解wheelEvent與mouseMove相關的方式,因此我感到很沮喪。 – Johnny

相關問題