2013-05-27 38 views
0

當QGraphicsScene項目在它的子項目後面時,我希望鼠標抓取器檢查後面的項目,然後抓取最頂端的項目,如果第一個沒有抓取。Qt鼠標事件傳播與場景項目

示例代碼:

from PySide.QtCore import * 
from PySide.QtGui import * 

class View(QGraphicsView): 
    pass 
class Scene(QGraphicsScene): 
    pass 

class ChildCircle(QGraphicsEllipseItem): 
    def __init__(self, parent): 
     super(ChildCircle, self).__init__() 
     self.setRect(QRect(-20,-20,70,70)) 
     self.setParentItem(parent) 

    def mousePressEvent(self, event): 
     print "Circle is Pressed", event.pos() 

class ParentRectangle(QGraphicsRectItem): 
    def __init__(self, scene): 
     super(ParentRectangle, self).__init__() 
     self.scene = scene 
     self.setRect(QRect(0,0,20,20)) 
     self.scene.addItem(self) 

     circle = ChildCircle(self) 

    def mousePressEvent(self, event): 
     print "Rectangle PRESS", event.pos() 


class Window(QMainWindow): 
    def __init__(self): 
     QMainWindow.__init__(self) 
     self.s = Scene() 
     self.s.setSceneRect(-200,-100,300,300,) 

     self.v = View(self.s) 
     self.v.setDragMode(QGraphicsView.ScrollHandDrag) 
     self.setCentralWidget(self.v) 

     ParentRectangle(self.s) 

if __name__ == '__main__': 
    import sys 
    app = QApplication(sys.argv) 
    window = Window() 
    window.resize(300, 200) 
    window.show() 
    sys.exit(app.exec_()) 

回答

2

我不知道我理解你的問題。在Qt的文檔明確指出以下有關mousePressEvent方法:

鼠標按下事件決定哪些項目應該成爲鼠標 採集。如果你重新實現這個功能,事件將默認爲 接受(見QEvent :: accept()),然後這個項目是鼠標 抓取器。這允許物品接收未來的移動,釋放和雙擊事件。如果您在事件中調用QEvent :: ignore(),則此項目 將失去鼠標抓取,並且事件將傳播到下面的任何最上面的項目

您所要做的就是決定是否調用QEvent::ignore方法。因此,例如,如果圓對象始終忽略鼠標按下事件,矩形對象將始終是鼠標抓取器(如果您單擊矩形)。在此代碼中,鼠標抓取器是您點擊過的物品。

class ChildCircle(QGraphicsEllipseItem): 
    def __init__(self, parent=None): 
     super(ChildCircle, self).__init__(parent) 
     self.setRect(QRect(-20,-20,70,70)) 
     self.setFlags(QGraphicsItem.ItemIsMovable) 

    def mousePressEvent(self, event): 
     # Ugly way to know there are items except self 
     if len(self.scene().items(event.scenePos())) > 1: 
      # Propogate the event to the parent 
      event.ignore() 

class ParentRectangle(QGraphicsRectItem): 
    def __init__(self, scene, parent=None): 
     super(ParentRectangle, self).__init__(parent) 
     self.scene = scene 
     self.setRect(QRect(0,0,20,20)) 
     self.scene.addItem(self) 
     circle = ChildCircle(self) 
     self.setFlags(QGraphicsItem.ItemIsMovable) 

    def mousePressEvent(self, event): 
     pass 
+1

非常感謝。它使我朝正確的方向發展。此外,我確信PySide文檔涵蓋了所有需求,但碰巧檢查Qt的「主」文檔也很明智。 – Alex