docstr: Update line with last point and current coordinates.
docstr_tok: ["Update","line","with","last","point","and","current","coordinates","."]
code: def mouseMoveEvent(self, ev):
      """Update line with last point and current coordinates."""
      pos = self.transformPos(ev.pos())
  
      # Update coordinates in status bar if image is opened
      window = self.parent().window()
      if window.filePath is not None:
          self.parent().window().labelCoordinates.setText(
              "X: %d; Y: %d" % (pos.x(), pos.y())
          )
  
      # Polygon drawing.
      if self.drawing():
          self.overrideCursor(CURSOR_DRAW)  # ?
          if self.current:
              # Display annotation width and height while drawing
              currentWidth = abs(self.current[0].x() - pos.x())
              currentHeight = abs(self.current[0].y() - pos.y())
              self.parent().window().labelCoordinates.setText(
                  "Width: %d, Height: %d / X: %d; Y: %d"
                  % (currentWidth, currentHeight, pos.x(), pos.y())
              )
  
              color = self.drawingLineColor
              if self.outOfPixmap(pos):
                  # Don't allow the user to draw outside the pixmap.
                  # Clip the coordinates to 0 or max,
                  # if they are outside the range [0, max]
                  size = self.pixmap.size()
                  clipped_x = min(max(0, pos.x()), size.width())
                  clipped_y = min(max(0, pos.y()), size.height())
                  pos = QPointF(clipped_x, clipped_y)
  
              elif len(self.current) > 1 and self.closeEnough(
                  pos, self.current[0]
              ):
                  # Attract line to starting point and colorise to alert the
                  # user:
                  pos = self.current[0]
                  color = self.current.line_color
                  self.overrideCursor(CURSOR_POINT)
                  self.current.highlightVertex(0, Shape.NEAR_VERTEX)
  
              if self.drawSquare:
                  self.line.points = [self.current[0], pos]
                  self.line.close()
  
              elif self.fourpoint:
                  self.line[0] = self.current[-1]
                  self.line[1] = pos
  
              else:
                  self.line[
                      1
                  ] = pos  # pos is the mouse's current position
  
              self.line.line_color = color
              self.prevPoint = QPointF()  # ？
              self.current.highlightClear()
          else:
              self.prevPoint = pos
          self.repaint()
          return
  
      # Polygon copy moving.
      if Qt.RightButton & ev.buttons():
          if self.selectedShapesCopy and self.prevPoint:
              self.overrideCursor(CURSOR_MOVE)
              self.boundedMoveShape(self.selectedShapesCopy, pos)
              self.repaint()
          elif self.selectedShapes:
              self.selectedShapesCopy = [
                  s.copy() for s in self.selectedShapes
              ]
              self.repaint()
          return
  
      # Polygon/Vertex moving.
      if Qt.LeftButton & ev.buttons():
          if self.selectedVertex():
              self.boundedMoveVertex(pos)
              self.shapeMoved.emit()
              self.repaint()
              self.movingShape = True
          elif self.selectedShapes and self.prevPoint:
              self.overrideCursor(CURSOR_MOVE)
              self.boundedMoveShape(self.selectedShapes, pos)
              self.shapeMoved.emit()
              self.repaint()
              self.movingShape = True
          else:
              # pan
              delta_x = pos.x() - self.pan_initial_pos.x()
              delta_y = pos.y() - self.pan_initial_pos.y()
              self.scrollRequest.emit(delta_x, Qt.Horizontal)
              self.scrollRequest.emit(delta_y, Qt.Vertical)
              self.update()
          return
  
      # Just hovering over the canvas, 2 posibilities:
      # - Highlight shapes
      # - Highlight vertex
      # Update shape/vertex fill and tooltip value accordingly.
      self.setToolTip("Image")
      for shape in reversed(
          [s for s in self.shapes if self.isVisible(s)]
      ):
          # Look for a nearby vertex to highlight. If that fails,
          # check if we happen to be inside a shape.
          index = shape.nearestVertex(pos, self.epsilon)
          if index is not None:
              if self.selectedVertex():
                  self.hShape.highlightClear()
              self.hVertex, self.hShape = index, shape
              shape.highlightVertex(index, shape.MOVE_VERTEX)
              self.overrideCursor(CURSOR_POINT)
              self.setToolTip("Click & drag to move point")
              self.setStatusTip(self.toolTip())
              self.update()
              break
          elif shape.containsPoint(pos):
              if self.selectedVertex():
                  self.hShape.highlightClear()
              self.hVertex, self.hShape = None, shape
              self.setToolTip(
                  "Click & drag to move shape '%s'" % shape.label
              )
              self.setStatusTip(self.toolTip())
              self.overrideCursor(CURSOR_GRAB)
              self.update()
              break
      else:  # Nothing found, clear highlights, reset state.
          if self.hShape:
              self.hShape.highlightClear()
              self.update()
          self.hVertex, self.hShape = None, None
          self.overrideCursor(CURSOR_DEFAULT)
  
imports: import copy
  from PyQt5.QtCore import Qt, pyqtSignal, QPointF, QPoint
  from PyQt5.QtGui import QPainter, QBrush, QColor, QPixmap
  from PyQt5.QtWidgets import QWidget, QMenu, QApplication
  from libs.shape import Shape
  from libs.utils import distance
label_desc: Use image node_id 12 for calling the Canvas obj's underlying member method code with example usage: obj.mouseMoveEvent(ev) without return types