Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Qt for Python
  4. Qt experts, using QPainter, how can I define a fill area between two QPainterPaths that are connected with straight lines?
Forum Updated to NodeBB v4.3 + New Features

Qt experts, using QPainter, how can I define a fill area between two QPainterPaths that are connected with straight lines?

Scheduled Pinned Locked Moved Unsolved Qt for Python
1 Posts 1 Posters 194 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • M Online
    M Online
    Mizmas
    wrote on last edited by Mizmas
    #1

    So I'm trying to create a fake 3D / isometric extrusion effect by creating a QPainterPath, duplicating and offsetting it, converting both to polygons, extracting their points and finally connecting these points with straight lines. This is the result:

    I can't figure out a way to fill between the lines with color, any help?

    Here's the full code to run the app from the .gif posted above:

    from PyQt6.QtGui import QPainter, QPainterPath, QFont, QPen, QBrush, QColor
    from PyQt6.QtCore import QPointF, Qt
    from PyQt6.QtWidgets import QApplication, QWidget, QSlider, QVBoxLayout
    import sys
    import math
    
    class TextPathPoints(QWidget):
        def __init__(self):
            super().__init__()
    
            self.resize(800, 300)
    
            # Create a QPainterPath with text
            self.font = QFont("Super Dessert", 120)  # Use a valid font
            self.path = QPainterPath()
            self.path.addText(100, 200, self.font, "HELLO!")
    
            # Control variables for extrusion
            self.extrusion_length = 25  # Length of extrusion
            self.extrusion_angle = 45  # Angle in degrees (measured counterclockwise from the positive x-axis)
    
            layout = QVBoxLayout()
    
            # Create slider for extrusion length (range 0-100, step 1)
            self.length_slider = QSlider()
            self.length_slider.setRange(0, 100)
            self.length_slider.setValue(self.extrusion_length)
            self.length_slider.setTickInterval(1)
            self.length_slider.valueChanged.connect(self.update_extrusion_length)
            layout.addWidget(self.length_slider)
    
            # Create slider for extrusion angle (range 0-360, step 1)
            self.angle_slider = QSlider()
            self.angle_slider.setRange(0, 360)
            self.angle_slider.setValue(self.extrusion_angle)
            self.angle_slider.setTickInterval(1)
            self.angle_slider.valueChanged.connect(self.update_extrusion_angle)
            layout.addWidget(self.angle_slider)
    
            self.setLayout(layout)
    
        def update_extrusion_length(self, value):
            self.extrusion_length = value
            self.update()  # Trigger repaint to update the path
    
        def update_extrusion_angle(self, value):
            self.extrusion_angle = value
            self.update()  # Trigger repaint to update the path
    
        def paintEvent(self, event):
            painter = QPainter(self)
            painter.setRenderHint(QPainter.RenderHint.Antialiasing)
    
            painter.setRenderHint(QPainter.RenderHint.Antialiasing)
    
            # Convert angle to radians
            angle_rad = math.radians(self.extrusion_angle)
    
            # Calculate x and y offsets based on extrusion length and angle
            self.offset_x = self.extrusion_length * math.cos(angle_rad)
            self.offset_y = self.extrusion_length * math.sin(angle_rad)
    
            # Duplicate the path
            self.duplicated_path = QPainterPath(self.path)  # Duplicate the original path
            self.duplicated_path.translate(self.offset_x, self.offset_y)  # Offset using calculated values
    
            # Convert paths to polygons
            original_polygon = self.path.toFillPolygon()
            duplicated_polygon = self.duplicated_path.toFillPolygon()
    
            # Extract points from polygons
            self.original_points = [(p.x(), p.y()) for p in original_polygon]
            self.duplicated_points = [(p.x(), p.y()) for p in duplicated_polygon]
    
            # Set brush for filling the path
            brush = QBrush(QColor("#ebd086"))  # Front and back fill
            painter.setBrush(brush)
    
            # Fill the original path
            painter.fillPath(self.path, brush)
    
            # Set pen for drawing lines between points
            pen = QPen()
            pen.setColor(QColor("black"))  # Color of the lines
            pen.setWidthF(1.4)
            painter.setPen(pen)
            pen.setJoinStyle(Qt.PenJoinStyle.RoundJoin)
            pen.setCapStyle(Qt.PenCapStyle.RoundCap)
    
            # Draw duplicated path
            painter.drawPath(self.duplicated_path)
    
            # Connect corresponding points between the original and duplicated paths
            num_points = min(len(self.original_points), len(self.duplicated_points))
            for i in range(num_points):
                original_x, original_y = self.original_points[i]
                duplicated_x, duplicated_y = self.duplicated_points[i]
                painter.drawLine(QPointF(original_x, original_y), QPointF(duplicated_x, duplicated_y))
    
            # Draw the original path
            painter.drawPath(self.path)
    
    
    app = QApplication(sys.argv)
    window = TextPathPoints()
    window.show()
    sys.exit(app.exec())
    
    
    
    1 Reply Last reply
    0

    • Login

    • Login or register to search.
    • First post
      Last post
    0
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Get Qt Extensions
    • Unsolved