如何解决QGraphicsPolygonItem插入顶点后多边形变形问题
问题分析
原代码大概率是未正确判断点击点是否在多边形线段范围内,或是插入顶点后未同步更新多边形与路径的顶点顺序,导致多边形连接关系错乱、出现变形。
正确实现代码
以下是可直接运行的修复代码,实现点击多边形边缘添加顶点且无变形的功能:
from PyQt5.QtWidgets import QApplication, QGraphicsScene, QGraphicsView, QGraphicsPolygonItem, QGraphicsPathItem from PyQt5.QtGui import QPolygonF, QPainterPath, QMouseEvent, QPen, QBrush from PyQt5.QtCore import Qt, QPointF, QLineF import sys class CustomGraphicsView(QGraphicsView): def __init__(self, parent=None): super().__init__(parent) self.scene = QGraphicsScene(self) self.setScene(self.scene) self.polygon_item = None self.path_item = None self.init_polygon() def init_polygon(self): # 初始化测试矩形多边形 polygon = QPolygonF([QPointF(100, 100), QPointF(300, 100), QPointF(300, 300), QPointF(100, 300)]) self.polygon_item = QGraphicsPolygonItem(polygon) self.polygon_item.setPen(QPen(Qt.red, 2)) self.polygon_item.setBrush(QBrush(Qt.transparent)) self.scene.addItem(self.polygon_item) # 同步创建路径项(虚线显示) path = QPainterPath() path.addPolygon(polygon) path.closeSubpath() self.path_item = QGraphicsPathItem(path) self.path_item.setPen(QPen(Qt.blue, 1, Qt.DashLine)) self.scene.addItem(self.path_item) def mousePressEvent(self, event: QMouseEvent): if event.button() != Qt.LeftButton: super().mousePressEvent(event) return click_pos = self.mapToScene(event.pos()) polygon = self.polygon_item.polygon() closest_edge_idx = -1 min_distance = float('inf') closest_point = QPointF() # 遍历所有边,筛选出距离点击点最近的有效线段 for i in range(polygon.count()): p1 = polygon[i] p2 = polygon[(i+1) % polygon.count()] line = QLineF(p1, p2) distance = line.distanceToPoint(click_pos) proj_point = line.pointAt(line.percentAt(click_pos)) # 判断投影点是否在线段范围内(避免点击到边的延长线) x_in_range = min(p1.x(), p2.x()) <= proj_point.x() <= max(p1.x(), p2.x()) y_in_range = min(p1.y(), p2.y()) <= proj_point.y() <= max(p1.y(), p2.y()) if x_in_range and y_in_range and distance < min_distance: min_distance = distance closest_edge_idx = i closest_point = proj_point # 距离阈值10像素,避免误操作 if closest_edge_idx != -1 and min_distance < 10: # 在目标边的后一位插入顶点,保证多边形连接顺序正确 polygon.insert(closest_edge_idx + 1, closest_point) self.polygon_item.setPolygon(polygon) # 同步更新路径项 path = QPainterPath() path.addPolygon(polygon) path.closeSubpath() self.path_item.setPath(path) super().mousePressEvent(event) if __name__ == "__main__": app = QApplication(sys.argv) view = CustomGraphicsView() view.setWindowTitle("添加多边形顶点") view.resize(600, 600) view.show() sys.exit(app.exec_())
关键修复点
- 限制点击范围:通过判断投影点是否在线段的坐标区间内,避免在边的延长线点击时错误添加顶点。
- 正确插入顶点:在目标边的索引后一位插入新顶点,严格保持多边形的顶点连接顺序。
- 同步更新双项:修改
QGraphicsPolygonItem后,必须重新生成QGraphicsPathItem的路径,确保两者图形一致。 - 添加误触防护:设置10像素的距离阈值,过滤远离多边形边的无效点击。
内容的提问来源于stack exchange,提问作者Paul_Dx
相关产品推荐
相关产品推荐

