【问题标题】:Hover event while clicking in PyQt单击 PyQt 时的悬停事件
【发布时间】:2017-09-30 18:40:06
【问题描述】:

在我的应用程序中,我有一个 QGraphicsScene,用户应该能够通过单击鼠标按钮并将鼠标悬停在项目上来更改项目的颜色。

下面是我从另一个问题借来的示例代码:

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

但是,有没有办法同时按住鼠标按钮并调用不同项目的悬停事件?

【问题讨论】:

  • 解释得更好,您的解释令人困惑,您希望它在按下项目和鼠标悬停在项目上时发生
  • 所以,我想点击该项目旁边的一个位置,当我将光标移到它上面时(并且仍然单击鼠标按钮)应该触发该项目的悬停事件。
  • 我了解你想要的事件,当它发生时你想做什么任务?
  • 该项目只是应该在 hoverEnterEvent 期间改变它的颜色。尽管我不确定这是否真的很重要。

标签: python pyqt pyqt5 qgraphicsscene qgraphicsitem


【解决方案1】:

问题在于使任务复杂化的事件组合,您可以传播mouseMoveEvent 事件,但不能对悬停事件执行相同的操作。一个简单的解决方案是实现QGraphicsView的方法mouseMoveEvent中的逻辑如下图:

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

【讨论】:

  • 我理解这个想法,也许这是正确的做法。但是将这段代码简单地复制到示例代码中实际上并没有做任何事情。当我单击并将鼠标悬停在某个项目上时,没有任何反应。
  • 由于您不回复我忘记更新我的答案,最终答案是我的答案加上您的答案。请再试一次。 :P
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-26
  • 1970-01-01
  • 1970-01-01
  • 2011-04-20
  • 2020-04-02
  • 1970-01-01
相关资源
最近更新 更多