def test_polygon_select(self): polygon = PolygonSelect(DaoPolygon([0, 0, 2, '1.0,2.0; 3.5,5.5'])) # 暂时不随着图形移动,编辑操作完成后直接重建 PolygonSelect polygon.setScale(1) self.assertEqual(20, polygon.MAR) self.assertEqual(-polygon.MAR + 1, polygon.dots_rect.x()) self.assertEqual(-polygon.MAR + 2, polygon.dots_rect.y()) self.assertEqual(polygon.MAR * 2 + 2.5, polygon.dots_rect.width()) self.assertEqual(polygon.MAR * 2 + 3.5, polygon.dots_rect.height()) polygon.setScale(2) self.assertEqual(10, polygon.MAR) self.assertEqual(-polygon.MAR + 1, polygon.dots_rect.x()) self.assertEqual(-polygon.MAR + 2, polygon.dots_rect.y()) self.assertEqual(polygon.MAR * 2 + 2.5, polygon.dots_rect.width()) self.assertEqual(polygon.MAR * 2 + 3.5, polygon.dots_rect.height()) polygon.set_offset(QPointF(1, 2)) self.assertEqual([[1.0, 2.0], [3.5, 5.5]], polygon.get_vertices()) polygon.apply_offset(QPointF(5, 6)) self.assertEqual([[6.0, 8.0], [8.5, 11.5]], polygon.get_vertices()) polygon.reset_offset() self.assertEqual([[1.0, 2.0], [3.5, 5.5]], polygon.get_vertices()) PolygonBase.move_point = True polygon.set_point_id(1) polygon.apply_offset(QPointF(10, 20)) self.assertEqual([[1.0, 2.0], [13.5, 25.5]], polygon.get_vertices()) polygon.confirm_offset() polygon.reset_offset() self.assertEqual([[1.0, 2.0], [13.5, 25.5]], polygon.get_vertices()) painter = mock.MagicMock() polygon.paint(painter, None)
class QMapGraphicsView(QGraphicsView): leftClick = pyqtSignal(QPointF) rightClick = pyqtSignal() mouseMove = pyqtSignal(QPointF) leftUp = pyqtSignal(QPointF) polygonCreated = pyqtSignal(list) polygonUpdated = pyqtSignal(list) pointsUpdated = pyqtSignal(list) def __init__(self, parent): super().__init__(parent) self.selected_polygon = None self.move_base = QPointF() self.new_polygon = None # slots @pyqtSlot(QPointF) def add_point(self, pt): self.new_polygon.add_point(pt) @pyqtSlot(QPointF) def pre_add_point(self, pt): # 按住鼠标并移动到点 self.new_polygon.pre_add_point(pt) self.scene().invalidate() @pyqtSlot() def remove_point(self): # 右键移除最新添加的点 self.new_polygon.remove_point() @pyqtSlot(QPointF) def set_move_mouse_base_point(self, pt): # 移动起点 self.move_base = pt @pyqtSlot(QPointF) def set_move_mouse_to_point(self, pt): # 移动到的点,左键按住 if self.selected_polygon is not None: offset = pt - self.move_base self.selected_polygon.set_offset(offset) self.scene().invalidate() @pyqtSlot(QPointF) def finish_move(self, pt): # 移动到的点,松开左键 if self.selected_polygon is not None: offset = pt - self.move_base self.selected_polygon.apply_offset(offset) self.pointsUpdated.emit(self.selected_polygon.get_points()) @pyqtSlot(QPointF) def reset_move(self): if self.selected_polygon is not None: self.selected_polygon.reset_offset() self.pointsUpdated.emit(self.selected_polygon.get_points()) def scale(self, sx, sy): super().scale(sx, sy) if self.selected_polygon is not None: self.selected_polygon.setScale(sx) self.scene().invalidate() def set_polygons(self, polygon_table, layer_num): """设置多边形 Args: polygon_table (dict[int, DaoPolygon]): 多边形表 layer_num (int): layer 总数 """ self.scene().clear() for polygon in polygon_table.values(): if polygon.layer < layer_num: self.scene().addItem(PolygonItem(polygon)) self.scene().setSceneRect(self.scene().itemsBoundingRect()) def set_selected_polygon(self, polygon): """绘制选中的多边形 Args: polygon (DaoPolygon): 列表中选中的多边形 """ if self.selected_polygon in self.scene().items(): self.scene().removeItem(self.selected_polygon) if polygon is not None: self.selected_polygon = PolygonSelect(polygon) self.selected_polygon.setScale(self.transform().m11()) self.scene().addItem(self.selected_polygon) self.scene().invalidate() def move_point(self, allow=True): """开始或停止移动点 Args: allow (bool): 是否移动 """ PolygonBase.move_point = allow def select_point(self, point_id): """选中一个点 Args: point_id (int): 选中的点的 id """ self.selected_polygon.set_point_id(point_id) self.scene().invalidate() def draw_closed_polygon(self, allow=True): """是否画封闭的多边形 即最后一个点是否连到第一个点 Args: allow (bool): 是否封闭 """ PolygonBase.close_polygon = allow self.scene().invalidate() def highlight_selection(self, allow=True): """是否突出显示选中的多边形(阴影覆盖) Args: allow (bool): 是否突出显示 """ PolygonBase.highlight_selection = allow self.scene().invalidate() def mark_points(self, allow=True): """是否突出显示选中的点 Args: allow (bool): 是否突出显示 """ PolygonBase.mark_points = allow self.scene().invalidate() def begin_insert(self): """开始插入多边形流程""" # data self.new_polygon = PolygonNew() self.scene().addItem(self.new_polygon) # signal self.leftUp.connect(self.add_point) self.leftClick.connect(self.pre_add_point) self.mouseMove.connect(self.pre_add_point) self.rightClick.connect(self.remove_point) def end_insert(self): """结束插入多边形流程""" # 处理新多边形 vertices = self.new_polygon.get_vertices() self.scene().removeItem(self.new_polygon) self.new_polygon = None if len(vertices) > 0: self.polygonCreated.emit(vertices) # signal self.leftUp.disconnect(self.add_point) self.leftClick.disconnect(self.pre_add_point) self.mouseMove.disconnect(self.pre_add_point) self.rightClick.disconnect(self.remove_point) def center_on_polygon(self, polygon): """视野中心移到多边形重心 Args: polygon (DaoPolygon): 目标多边形 """ if polygon is not None: ax, ay = polygon.get_com() center_of_mass = QPointF(ax, ay) self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.centerOn(center_of_mass) self.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded) self.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded) def begin_move(self): """开始移动流程""" # data self.pointsUpdated.emit(self.selected_polygon.get_points()) # signal self.leftClick.connect(self.set_move_mouse_base_point) self.mouseMove.connect(self.set_move_mouse_to_point) self.leftUp.connect(self.finish_move) self.rightClick.connect(self.reset_move) def end_move(self): """结束移动流程""" # data if self.selected_polygon is not None: self.selected_polygon.confirm_offset() vertices = self.selected_polygon.get_vertices() self.polygonUpdated.emit(vertices) # signal self.leftClick.disconnect(self.set_move_mouse_base_point) self.mouseMove.disconnect(self.set_move_mouse_to_point) self.leftUp.disconnect(self.finish_move) self.rightClick.disconnect(self.reset_move) def mousePressEvent(self, event): # 鼠标按下 button = event.button() pt = self.mapToScene(event.pos()) if button == Qt.LeftButton: self.leftClick.emit(pt) elif button == Qt.RightButton: self.rightClick.emit() self.scene().invalidate() def mouseMoveEvent(self, event): # 鼠标移动 pt = self.mapToScene(event.pos()) if event.buttons() == Qt.LeftButton: self.mouseMove.emit(pt) def mouseReleaseEvent(self, event): # 鼠标释放 button = event.button() pt = self.mapToScene(event.pos()) if button == Qt.LeftButton: self.leftUp.emit(pt)