您将需要自己调整大小。要做到这一点,你需要继承
QGraphicsRectItem和实现鼠标事件处理函数:
mousePressEvent,
mouseMoveEvent,
mouseReleaseEvent。总体思路如下:
- 您创建了一组手柄,可用于调整形状的大小。
- 通过跟踪手柄位置变化,可以计算形状的新几何形状。
我之前写过一些代码,该代码可以完美地与PyQt5一起使用,但也应该与PyQt4一起使用。您应该能够使其适应您的需求:
import sysfrom PyQt5.QtCore import Qt, QRectF, QPointFfrom PyQt5.QtGui import QBrush, QPainterPath, QPainter, QColor, QPen, QPixmapfrom PyQt5.QtWidgets import QGraphicsRectItem, QApplication, QGraphicsView, QGraphicsScene, QGraphicsItemclass GraphicsRectItem(QGraphicsRectItem): handleTopLeft = 1 handleTopMiddle = 2 handleTopRight = 3 handleMiddleLeft = 4 handleMiddleRight = 5 handleBottomLeft = 6 handleBottomMiddle = 7 handleBottomRight = 8 handleSize = +8.0 handleSpace = -4.0 handleCursors = { handleTopLeft: Qt.SizeFDiagCursor, handleTopMiddle: Qt.SizeVerCursor, handleTopRight: Qt.SizeBDiagCursor, handleMiddleLeft: Qt.SizeHorCursor, handleMiddleRight: Qt.SizeHorCursor, handleBottomLeft: Qt.SizeBDiagCursor, handleBottomMiddle: Qt.SizeVerCursor, handleBottomRight: Qt.SizeFDiagCursor, } def __init__(self, *args): """ Initialize the shape. """ super().__init__(*args) self.handles = {} self.handleSelected = None self.mousePressPos = None self.mousePressRect = None self.setAcceptHoverEvents(True) self.setFlag(QGraphicsItem.ItemIsMovable, True) self.setFlag(QGraphicsItem.ItemIsSelectable, True) self.setFlag(QGraphicsItem.ItemSendsGeometryChanges, True) self.setFlag(QGraphicsItem.ItemIsFocusable, True) self.updateHandlesPos() def handleAt(self, point): """ Returns the resize handle below the given point. """ for k, v, in self.handles.items(): if v.contains(point): return k return None def hoverMoveEvent(self, moveEvent): """ Executed when the mouse moves over the shape (NOT PRESSED). """ if self.isSelected(): handle = self.handleAt(moveEvent.pos()) cursor = Qt.ArrowCursor if handle is None else self.handleCursors[handle] self.setCursor(cursor) super().hoverMoveEvent(moveEvent) def hoverLeaveEvent(self, moveEvent): """ Executed when the mouse leaves the shape (NOT PRESSED). """ self.setCursor(Qt.ArrowCursor) super().hoverLeaveEvent(moveEvent) def mousePressEvent(self, mouseEvent): """ Executed when the mouse is pressed on the item. """ self.handleSelected = self.handleAt(mouseEvent.pos()) if self.handleSelected: self.mousePressPos = mouseEvent.pos() self.mousePressRect = self.boundingRect() super().mousePressEvent(mouseEvent) def mouseMoveEvent(self, mouseEvent): """ Executed when the mouse is being moved over the item while being pressed. """ if self.handleSelected is not None: self.interactiveResize(mouseEvent.pos()) else: super().mouseMoveEvent(mouseEvent) def mouseReleaseEvent(self, mouseEvent): """ Executed when the mouse is released from the item. """ super().mouseReleaseEvent(mouseEvent) self.handleSelected = None self.mousePressPos = None self.mousePressRect = None self.update() def boundingRect(self): """ Returns the bounding rect of the shape (including the resize handles). """ o = self.handleSize + self.handleSpace return self.rect().adjusted(-o, -o, o, o) def updateHandlesPos(self): """ Update current resize handles according to the shape size and position. """ s = self.handleSize b = self.boundingRect() self.handles[self.handleTopLeft] = QRectF(b.left(), b.top(), s, s) self.handles[self.handleTopMiddle] = QRectF(b.center().x() - s / 2, b.top(), s, s) self.handles[self.handleTopRight] = QRectF(b.right() - s, b.top(), s, s) self.handles[self.handleMiddleLeft] = QRectF(b.left(), b.center().y() - s / 2, s, s) self.handles[self.handleMiddleRight] = QRectF(b.right() - s, b.center().y() - s / 2, s, s) self.handles[self.handleBottomLeft] = QRectF(b.left(), b.bottom() - s, s, s) self.handles[self.handleBottomMiddle] = QRectF(b.center().x() - s / 2, b.bottom() - s, s, s) self.handles[self.handleBottomRight] = QRectF(b.right() - s, b.bottom() - s, s, s) def interactiveResize(self, mousePos): """ Perform shape interactive resize. """ offset = self.handleSize + self.handleSpace boundingRect = self.boundingRect() rect = self.rect() diff = QPointF(0, 0) self.prepareGeometryChange() if self.handleSelected == self.handleTopLeft: fromX = self.mousePressRect.left() fromY = self.mousePressRect.top() toX = fromX + mousePos.x() - self.mousePressPos.x() toY = fromY + mousePos.y() - self.mousePressPos.y() diff.setX(toX - fromX) diff.setY(toY - fromY) boundingRect.setLeft(toX) boundingRect.setTop(toY) rect.setLeft(boundingRect.left() + offset) rect.setTop(boundingRect.top() + offset) self.setRect(rect) elif self.handleSelected == self.handleTopMiddle: fromY = self.mousePressRect.top() toY = fromY + mousePos.y() - self.mousePressPos.y() diff.setY(toY - fromY) boundingRect.setTop(toY) rect.setTop(boundingRect.top() + offset) self.setRect(rect) elif self.handleSelected == self.handleTopRight: fromX = self.mousePressRect.right() fromY = self.mousePressRect.top() toX = fromX + mousePos.x() - self.mousePressPos.x() toY = fromY + mousePos.y() - self.mousePressPos.y() diff.setX(toX - fromX) diff.setY(toY - fromY) boundingRect.setRight(toX) boundingRect.setTop(toY) rect.setRight(boundingRect.right() - offset) rect.setTop(boundingRect.top() + offset) self.setRect(rect) elif self.handleSelected == self.handleMiddleLeft: fromX = self.mousePressRect.left() toX = fromX + mousePos.x() - self.mousePressPos.x() diff.setX(toX - fromX) boundingRect.setLeft(toX) rect.setLeft(boundingRect.left() + offset) self.setRect(rect) elif self.handleSelected == self.handleMiddleRight: print("MR") fromX = self.mousePressRect.right() toX = fromX + mousePos.x() - self.mousePressPos.x() diff.setX(toX - fromX) boundingRect.setRight(toX) rect.setRight(boundingRect.right() - offset) self.setRect(rect) elif self.handleSelected == self.handleBottomLeft: fromX = self.mousePressRect.left() fromY = self.mousePressRect.bottom() toX = fromX + mousePos.x() - self.mousePressPos.x() toY = fromY + mousePos.y() - self.mousePressPos.y() diff.setX(toX - fromX) diff.setY(toY - fromY) boundingRect.setLeft(toX) boundingRect.setBottom(toY) rect.setLeft(boundingRect.left() + offset) rect.setBottom(boundingRect.bottom() - offset) self.setRect(rect) elif self.handleSelected == self.handleBottomMiddle: fromY = self.mousePressRect.bottom() toY = fromY + mousePos.y() - self.mousePressPos.y() diff.setY(toY - fromY) boundingRect.setBottom(toY) rect.setBottom(boundingRect.bottom() - offset) self.setRect(rect) elif self.handleSelected == self.handleBottomRight: fromX = self.mousePressRect.right() fromY = self.mousePressRect.bottom() toX = fromX + mousePos.x() - self.mousePressPos.x() toY = fromY + mousePos.y() - self.mousePressPos.y() diff.setX(toX - fromX) diff.setY(toY - fromY) boundingRect.setRight(toX) boundingRect.setBottom(toY) rect.setRight(boundingRect.right() - offset) rect.setBottom(boundingRect.bottom() - offset) self.setRect(rect) self.updateHandlesPos() def shape(self): """ Returns the shape of this item as a QPainterPath in local coordinates. """ path = QPainterPath() path.addRect(self.rect()) if self.isSelected(): for shape in self.handles.values(): path.addEllipse(shape) return path def paint(self, painter, option, widget=None): """ Paint the node in the graphic view. """ painter.setBrush(QBrush(QColor(255, 0, 0, 100))) painter.setPen(QPen(QColor(0, 0, 0), 1.0, Qt.SolidLine)) painter.drawRect(self.rect()) painter.setRenderHint(QPainter.Antialiasing) painter.setBrush(QBrush(QColor(255, 0, 0, 255))) painter.setPen(QPen(QColor(0, 0, 0, 255), 1.0, Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin)) for handle, rect in self.handles.items(): if self.handleSelected is None or handle == self.handleSelected: painter.drawEllipse(rect)def main(): app = QApplication(sys.argv) grview = QGraphicsView() scene = QGraphicsScene() scene.setSceneRect(0, 0, 680, 459) scene.addPixmap(QPixmap('01.png')) grview.setScene(scene) item = GraphicsRectItem(0, 0, 300, 150) scene.addItem(item) grview.fitInView(scene.sceneRect(), Qt.KeepAspectRatio) grview.show() sys.exit(app.exec_())if __name__ == '__main__': main()


