pyqt5 我有一个graphicsView 控件,请问怎么为他增加鼠标框选红色矩形并返回矩形在图片上的实际坐标的功能,不需要创建子类的情况下
时间: 2024-02-24 17:58:00 浏览: 185
要为一个现有的GraphicsView控件增加鼠标框选红色矩形并返回矩形在图片上的实际坐标,可以通过以下步骤实现:
1. 在创建GraphicsView控件时,设置其鼠标跟踪属性为True,以便捕捉鼠标移动事件。
2. 为GraphicsView控件的鼠标按下、移动、释放事件分别绑定相应的槽函数。
3. 在鼠标按下事件槽函数中,创建一个矩形图元,颜色设为红色,并设置不透明度为0.5,将其添加到场景中。
4. 在鼠标移动事件槽函数中,更新矩形图元的位置和大小,以实现框选的效果。
5. 在鼠标释放事件槽函数中,计算出矩形框选区域在图片上的实际坐标,并返回给调用者。
下面是一个示例代码,可以参考实现:
```python
from PyQt5.QtWidgets import QGraphicsView, QGraphicsScene, QGraphicsRectItem
from PyQt5.QtCore import QPointF, Qt
class MyGraphicsView(QGraphicsView):
def __init__(self, parent=None):
super().__init__(parent)
self.setMouseTracking(True)
self.scene = QGraphicsScene(self)
self.setScene(self.scene)
self.rubberBand = None
self.startPos = None
self.endPos = None
self.clicked = False
self.viewport().installEventFilter(self)
def eventFilter(self, obj, event):
if obj is self.viewport() and event.type() == Qt.QEvent.MouseButtonPress:
self.clicked = True
return super(MyGraphicsView, self).eventFilter(obj, event)
def mousePressEvent(self, event):
if event.button() == Qt.LeftButton and self.clicked:
self.startPos = event.pos()
self.endPos = event.pos()
self.rubberBand = QGraphicsRectItem()
self.rubberBand.setPen(Qt.red)
self.rubberBand.setBrush(Qt.red)
self.rubberBand.setOpacity(0.5)
self.scene.addItem(self.rubberBand)
def mouseMoveEvent(self, event):
if self.rubberBand is not None:
self.endPos = event.pos()
x1, y1 = self.mapToScene(self.startPos).toPoint().x(), self.mapToScene(self.startPos).toPoint().y()
x2, y2 = self.mapToScene(self.endPos).toPoint().x(), self.mapToScene(self.endPos).toPoint().y()
self.rubberBand.setRect(QPointF(x1, y1).x(), QPointF(x1, y1).y(), x2 - x1, y2 - y1)
def mouseReleaseEvent(self, event):
if event.button() == Qt.LeftButton and self.clicked:
self.clicked = False
x1, y1 = self.mapToScene(self.startPos).toPoint().x(), self.mapToScene(self.startPos).toPoint().y()
x2, y2 = self.mapToScene(self.endPos).toPoint().x(), self.mapToScene(self.endPos).toPoint().y()
rect = self.rubberBand.rect()
rect = rect.normalized()
x, y = rect.x(), rect.y()
w, h = rect.width(), rect.height()
x, y = x + x1, y + y1
w, h = w, h
self.scene.removeItem(self.rubberBand)
self.rubberBand = None
self.startPos = None
self.endPos = None
# 计算矩形框选区域在图片上的实际坐标
# 这里需要根据具体情况修改
# 确定图像的坐标系和比例关系
# 比如如果场景中显示的是一张图片,可以这样计算:
# img = self.scene.items()[0]
# scale = img.transform().m11()
# imgRect = img.boundingRect()
# x = (x - imgRect.x()) / scale
# y = (y - imgRect.y()) / scale
# w = w / scale
# h = h / scale
# print(x, y, w, h)
# 返回矩形框选区域在图片上的实际坐标
return (x, y, w, h)
```
在以上代码中,我们为GraphicsView控件增加了鼠标按下、移动、释放事件,并绑定了相应的槽函数。在鼠标按下事件槽函数中,我们创建了一个矩形图元,并将其添加到场景中。在鼠标移动事件槽函数中,更新矩形图元的位置和大小,实现了框选的效果。在鼠标释放事件槽函数中,计算出矩形框选区域在图片上的实际坐标,并返回给调用者。在计算实际坐标时,需要根据具体情况修改,比如确定图像的坐标系和比例关系。
阅读全文