在 PyQt 中单击时悬停事件
Hover event while clicking in PyQt
在我的应用程序中,我有一个 QGraphicsScene,用户应该能够通过单击鼠标按钮并将鼠标悬停在项目上来更改项目的颜色。
下面是我从另一个问题借来的示例代码:
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 "decides which graphics item it is that receives mouse events" 以某种方式阻止其他项目的鼠标事件。
但是,有没有办法同时按住鼠标按钮并调用不同项目的悬停事件?
问题是事件的组合使任务变得复杂,您可以传播 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()
在我的应用程序中,我有一个 QGraphicsScene,用户应该能够通过单击鼠标按钮并将鼠标悬停在项目上来更改项目的颜色。
下面是我从另一个问题借来的示例代码:
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 "decides which graphics item it is that receives mouse events" 以某种方式阻止其他项目的鼠标事件。
但是,有没有办法同时按住鼠标按钮并调用不同项目的悬停事件?
问题是事件的组合使任务变得复杂,您可以传播 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()