pyqt5 我有一个graphicsView 控件,不需要创建子类的情况下,请问怎么为他增加鼠标框选红色矩形并返回矩形在图片上的实际坐标的功能,不需要创建子类的情况下
时间: 2024-02-24 11:58:16 浏览: 55
您可以通过为graphicsView的鼠标事件添加事件过滤器来实现鼠标框选红色矩形的功能,并且可以使用QRectF.map方法将矩形坐标映射到图片上的实际坐标。
具体的代码实现如下:
```python
from PyQt5.QtGui import QBrush, QColor, QPainter, QPen
from PyQt5.QtCore import QRectF, Qt
from PyQt5.QtWidgets import QGraphicsView, QGraphicsScene
class MyGraphicsView(QGraphicsView):
def __init__(self, parent=None):
super().__init__(parent)
self.setMouseTracking(True)
self._rubber_band_rect = None
self._rubber_band_is_shown = False
self._start_pos = None
self._end_pos = None
self.setScene(QGraphicsScene(self))
self.setBackgroundBrush(QBrush(QColor(220, 220, 220)))
def eventFilter(self, obj, event):
if obj is self.viewport() and event.type() == event.MouseMove:
if self._start_pos is not None:
self._end_pos = event.pos()
self.showRubberBand()
elif obj is self.viewport() and event.type() == event.MouseButtonPress:
if event.button() == Qt.LeftButton:
self._start_pos = event.pos()
self._end_pos = self._start_pos
elif obj is self.viewport() and event.type() == event.MouseButtonRelease:
if event.button() == Qt.LeftButton:
self.hideRubberBand()
self._start_pos = None
self._end_pos = None
return super().eventFilter(obj, event)
def showRubberBand(self):
if not self._rubber_band_is_shown:
self._rubber_band_rect = QRectF(self._start_pos, self._end_pos)
self._rubber_band_rect = self._rubber_band_rect.normalized()
self._rubber_band_is_shown = True
self.viewport().update()
def hideRubberBand(self):
if self._rubber_band_is_shown:
self._rubber_band_is_shown = False
self.viewport().update()
rect = self.mapToScene(self._rubber_band_rect).boundingRect()
print('Selected rectangle:', rect)
def paintEvent(self, event):
super().paintEvent(event)
if self._rubber_band_is_shown:
painter = QPainter(self.viewport())
painter.setPen(QPen(Qt.red))
painter.setBrush(QBrush(QColor(255, 255, 255, 100)))
painter.drawRect(self._rubber_band_rect)
painter.end()
def resizeEvent(self, event):
super().resizeEvent(event)
self.setSceneRect(self.viewport().rect())
```
在这段代码中,我们继承了QGraphicsView类,并在其中添加了事件过滤器来处理鼠标事件。在鼠标移动、鼠标按下、鼠标释放事件中,我们分别记录了矩形框选的起始点、终止点,并在鼠标移动事件中实时更新矩形框选的显示。在鼠标释放事件中,我们隐藏了矩形框选,并使用QRectF.map方法将矩形坐标映射到图片上的实际坐标。
最后,在paintEvent方法中,我们绘制了红色的矩形框选,并在resizeEvent方法中更新了场景的大小。
使用该MyGraphicsView类替换graphicsView即可实现您的需求。
阅读全文