I have this Ruler class Right now the scale looks like the below image. I want the ticks to have their roots towards the view instead of having them outwards. The base of the scale should be inside. I am not able to get the roots to the scales inner border(the black line). Here is my code for the class: class Ruler(QWidget): def __init__(self, orientation=Qt.Orientation.Horizontal, parent=None): super().__init__(parent) self._orientation = orientation self._origin = 0.0 self._unit = 1.0 self._zoom = 1.0 self._mouse_tracking = False self._draw_text = False self._cursor_pos = QPoint() self.setMouseTracking(True) f = QFont("Courier", 9) f.setStyleHint(QFont.StyleHint.TypeWriter) self.setFont(f) # Ensure room for labels inside the ruler if orientation == Qt.Orientation.Horizontal: self.setFixedHeight(RULER_BREADTH + 5) else: self.setFixedWidth(RULER_BREADTH + 5) def minimumSizeHint(self): return self.sizeHint() # We'll constrain via layout if needed def sizeHint(self): if self._orientation == Qt.Orientation.Horizontal: return super().sizeHint().expandedTo(self.minimumSizeHint()).boundedTo(self.minimumSizeHint()) return super().sizeHint().expandedTo(self.minimumSizeHint()).boundedTo(self.minimumSizeHint()) def paintEvent(self, event): painter = QPainter(self) painter.setRenderHints( QPainter.RenderHint.Antialiasing | QPainter.RenderHint.TextAntialiasing ) # Fill background painter.fillRect(self.rect(), QColor(236, 233, 216)) # Minor ticks: every 1 mm, length = 1/3 of breadth self._draw_scale(painter, mm_interval=1, tick_length=RULER_BREADTH / 3, draw_labels=False) # Medium ticks: every 5 mm, length = 2/3 of breadth self._draw_scale(painter, mm_interval=5, tick_length=RULER_BREADTH * 2 / 3, draw_labels=False) # Major ticks: every 10 mm, full length, with labels self._draw_scale(painter, mm_interval=10, tick_length=RULER_BREADTH, draw_labels=True) # Draw mouse position indicator if self._mouse_tracking: painter.setOpacity(0.4) # assume _draw_mouse_tick exists self._draw_mouse_tick(painter) painter.setOpacity(1.0) # Draw border line painter.setPen(QPen(Qt.GlobalColor.black, 2)) if self._orientation == Qt.Orientation.Horizontal: painter.drawLine(self.rect().bottomLeft(), self.rect().bottomRight()) else: painter.drawLine(self.rect().topRight(), self.rect().bottomRight()) def _draw_scale(self, painter, mm_interval, tick_length, draw_labels=False): is_horz = (self._orientation == Qt.Orientation.Horizontal) length = self.width() if is_horz else self.height() # Compute pixels-per-mm from DPI screen = QApplication.primaryScreen() dpi = (screen.logicalDotsPerInchX() if is_horz else screen.logicalDotsPerInchY()) px_per_mm = dpi / 25.4 step_pix = mm_interval * px_per_mm * self._zoom # Determine visible tick indices first_tick = int(self._origin // step_pix) - 1 last_tick = int((self._origin + length) // step_pix) + 1 for tick in range(first_tick, last_tick + 1): scene_pos = tick * step_pix screen_pos = scene_pos - self._origin if screen_pos < 0 or screen_pos > length: continue # Draw the tick line painter.setPen(QPen(Qt.GlobalColor.red, 1)) if is_horz: painter.drawLine( QPointF(screen_pos, 0), QPointF(screen_pos, tick_length) ) else: painter.drawLine( QPointF(0, screen_pos), QPointF(tick_length, screen_pos) ) # Draw the label inside the ruler if draw_labels and (tick % (10 // mm_interval) == 0): label = str(abs(tick * mm_interval)) painter.setPen(QPen(Qt.GlobalColor.black)) if is_horz: x = int(screen_pos + 2) y = int(tick_length - 10) painter.drawText(x, y, label) else: painter.save() tx = tick_length - 2 ty = screen_pos + 2 painter.translate(tx, ty) painter.rotate(-90) painter.drawText(0, 0, label) painter.restore() def _draw_mouse_tick(self, painter): if self._orientation == Qt.Orientation.Horizontal: x = self._cursor_pos.x() painter.drawLine(QPointF(x, 0), QPointF(x, self.height())) else: y = self._cursor_pos.y() painter.drawLine(QPointF(0, y), QPointF(self.width(), y)) def mouseMoveEvent(self, event): self._cursor_pos = event.position().toPoint() self.update() super().mouseMoveEvent(event) def setOrigin(self, val): self._origin = val self.update() def setUnit(self, val): self._unit = val self.update() def setZoom(self, val): self._zoom = val self.update() def setMouseTrack(self, track: bool): self._mouse_tracking = track self.update() @staticmethod def toMM(orientation: Qt.Orientation) -> float: screen = QApplication.primaryScreen() if orientation == Qt.Orientation.Horizontal: dpi = screen.logicalDotsPerInchX() else: dpi = screen.logicalDotsPerInchY() # 1 inch = 25.4 mm → mm per pixel = 25.4 mm / (dots per inch) return 25.4 / dpi Can anyone please help me solve the issue. If could specify the direction of the ruler's base dynamically that would be better. Thank you : Continue reading...