2017-09-30 62 views
1

在我的應用程序中,我有一個QGraphicsScene,用戶應該可以通過鼠標按鈕單擊並懸停在項目上來更改項目的顏色。單擊PyQt時懸停事件

下面是一個例子代碼,這是我從另一個問題借來的:

PyQt: hover and click events for graphicscene ellipse

from PyQt5 import QtGui, QtCore, QtWidgets 

class MyFrame(QtWidgets.QGraphicsView): 
    def __init__(self, parent = None): 
     super(MyFrame, self).__init__(parent) 

     self.setScene(QtWidgets.QGraphicsScene()) 

     # add some items 
     x = 0 
     y = 0 
     w = 15 
     h = 15 
     pen = QtGui.QPen(QtGui.QColor(QtCore.Qt.green)) 
     brush = QtGui.QBrush(pen.color().darker(150)) 

     # i want a mouse over and mouse click event for this ellipse 
     for xi in range(3): 
      for yi in range(3): 
       item = callbackRect(x+xi*30, y+yi*30, w, h) 
       item.setAcceptHoverEvents(True) 
       item.setPen(pen) 
       item.setBrush(brush) 
       self.scene().addItem(item) 
       item.setFlag(QtWidgets.QGraphicsItem.ItemIsMovable) 

class callbackRect(QtWidgets.QGraphicsRectItem): 
    ''' 
    Rectangle call-back class. 
    ''' 

    def mouseReleaseEvent(self, event): 
     # recolor on click 
     color = QtGui.QColor(180, 174, 185) 
     brush = QtGui.QBrush(color) 
     QtWidgets.QGraphicsRectItem.setBrush(self, brush) 

     return QtWidgets.QGraphicsRectItem.mouseReleaseEvent(self, event) 

    def hoverMoveEvent(self, event): 
     # Do your stuff here. 
     pass 

    def hoverEnterEvent(self, event): 
     color = QtGui.QColor(0, 174, 185) 
     brush = QtGui.QBrush(color) 
     QtWidgets.QGraphicsRectItem.setBrush(self, brush) 

    def hoverLeaveEvent(self, event): 
     color = QtGui.QColor(QtCore.Qt.green) 
     brush = QtGui.QBrush(color.darker(150)) 
     QtWidgets.QGraphicsRectItem.setBrush(self, brush) 

if (__name__ == '__main__'): 
    app = QtWidgets.QApplication([]) 
    f = MyFrame() 
    f.show() 
    app.exec_() 

因此,在這種代碼的懸停方法只有當沒有按下鼠標鍵調用。如文檔中所述(用於PySide),mousePressEvent「決定它接收鼠標事件的圖形項目」,它以某種方式阻止其他項目的鼠標事件。

https://deptinfo-ensip.univ-poitiers.fr/ENS/pyside-docs/PySide/QtGui/QGraphicsItem.html?highlight=graphicsitem#PySide.QtGui.PySide.QtGui.QGraphicsItem.mouseMoveEvent

但是,有沒有辦法同時按住鼠標按鈕,並調用不同的項目的懸停事件?

+0

更好的解釋,你的解釋是混亂的,你希望在項目按這樣的情況發生,當鼠標懸停的項目 – eyllanesc

+0

所以,我想單擊項目旁邊的某個位置,同時將光標移動到該位置上(並且仍然單擊鼠標按鈕),應該觸發該項目的懸停事件。 –

+0

我瞭解你想要的事件,當它發生時你想要做什麼任務? – eyllanesc

回答

1

問題是導致任務複雜的事件組合,您可以傳播mouseMoveEvent事件,但您無法對懸停事件執行相同的操作。一個簡單的解決方案是實現該方法的QGraphicsViewmouseMoveEvent邏輯如下圖所示:

class MyFrame(QtWidgets.QGraphicsView): 
    def __init__(self, parent = None): 
     super(MyFrame, self).__init__(parent)  
     self.setScene(QtWidgets.QGraphicsScene()) 
     [...] 

    itemsSelected = [] 
    def mouseMoveEvent(self, event): 
     QtWidgets.QGraphicsView.mouseMoveEvent(self, event) 
     items = self.items(event.pos())#, QtGui.QTransform()) 
     for item in self.itemsSelected: 
      if item in items: 
       item.enterColor() 
      else: 
       item.leaveColor() 
     self.itemsSelected = items 

class callbackRect(QtWidgets.QGraphicsRectItem): 
    ''' 
    Rectangle call-back class. 
    ''' 
    def enterColor(self): 
     color = QtGui.QColor(0, 174, 185) 
     brush = QtGui.QBrush(color) 
     QtWidgets.QGraphicsRectItem.setBrush(self, brush) 

    def leaveColor(self): 
     color = QtGui.QColor(QtCore.Qt.green) 
     brush = QtGui.QBrush(color.darker(150)) 
     QtWidgets.QGraphicsRectItem.setBrush(self, brush) 

    def hoverEnterEvent(self, event): 
     self.enterColor() 

    def hoverLeaveEvent(self, event): 
     self.leaveColor() 
+0

我理解這個想法,可能它是正確的選擇。但是將這些代碼簡單地複製到示例代碼中實際上並沒有做任何事情。當我點擊並懸停在項目上時,什麼也沒有發生。 –

+0

因爲你沒有迴應,我忘了更新我的答案,最後的答案是我的答案加上你的答案。請再試一次。 :P – eyllanesc