2017-09-30 4 views
1

Dans mon application, j'ai un QGraphicsScene où l'utilisateur devrait être en mesure de changer la couleur des éléments en cliquant sur le bouton de la souris et passer la souris sur les éléments.Survolez l'événement en cliquant sur PyQt

Ci-dessous un exemple de code que j'emprunté à une autre question:

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_() 

Ainsi, dans ce code, les méthodes de vol stationnaire ne sont appelés quand il n'y a pas de bouton de la souris enfoncé. Comme indiqué dans la documentation (pour PySide), mousePressEvent "décide quel élément graphique reçoit les événements de la souris", ce qui bloque d'une certaine manière les événements de la souris pour les autres éléments.

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

Cependant, est-il un moyen de tenir simultanément sur le bouton de la souris enfoncé et appeler les événements de vol stationnaire de différents éléments?

+0

Expliquer mieux, votre explication est source de confusion, vous voulez que cela se produise lorsque l'élément est pressé et lorsque la souris est plané l'élément – eyllanesc

+0

Donc, je veux cliquer à une position à côté de l'élément et pendant que je déplace le curseur dessus (et le bouton de la souris est encore cliqué) un événement de survol de cet élément doit être déclenché. –

+0

Je comprends l'événement que vous voulez, quelle tâche voulez-vous faire quand cela arrive? – eyllanesc

Répondre

1

Le problème est la combinaison d'événements qui rend la tâche compliquée, vous pouvez propager l'événement mouseMoveEvent mais vous ne pouvez pas faire la même chose avec les événements hover. Une solution simple consiste à mettre en œuvre la logique dans la méthode mouseMoveEvent de QGraphicsView comme indiqué ci-dessous:

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

Je comprends l'idée et c'est probablement la bonne façon d'y aller. Mais copier ce code simplement dans l'exemple de code ne fait rien. Lorsque je clique et que je survole un objet, rien ne se passe. –

+0

Comme vous ne répondez pas, j'oublie de mettre à jour ma réponse, la réponse finale est l'union de ma réponse et de votre réponse. Essayez-le à nouveau s'il vous plaît. : P – eyllanesc