Ejemplo n.º 1
0
 def paintEvent(self, event: QPaintEvent) -> None:
     painter = QStylePainter(self)
     opt = QStyleOptionSlider()
     self.initStyleOption(opt)
     if self.tickPosition() != QSlider.NoTicks:
         x = 4
         for i in range(self.minimum(), self.width(), x):
             if i % 5 == 0:
                 h = 18
                 w = 1
                 z = 8
             else:
                 h = 7
                 w = 0.8
                 z = 15
             pen = QPen(QColor('#444'))
             pen.setWidthF(w)
             painter.setPen(pen)
             if self.tickPosition() in (QSlider.TicksBothSides, QSlider.TicksAbove):
                 y = self.rect().top() + z
                 painter.drawLine(x, y, x, y + h)
             if self.tickPosition() in (QSlider.TicksBothSides, QSlider.TicksBelow):
                 y = self.rect().bottom() - z
                 painter.drawLine(x, y, x, y - h)
             x += 10
     opt.subControls = QStyle.SC_SliderGroove
     painter.drawComplexControl(QStyle.CC_Slider, opt)
     for path in self._regions:
         brushcolor = QColor(150, 190, 78, 185) if self._regions.index(path) == self._regionSelected \
             else QColor(237, 242, 255, 185)
         painter.setBrush(brushcolor)
         painter.setPen(Qt.NoPen)
         painter.drawPath(path)
     opt.subControls = QStyle.SC_SliderHandle
     painter.drawComplexControl(QStyle.CC_Slider, opt)
Ejemplo n.º 2
0
 def paintEvent(self, event: QPaintEvent) -> None:
     painter = QStylePainter(self)
     opt = QStyleOptionSlider()
     self.initStyleOption(opt)
     if self.tickPosition() != QSlider.NoTicks:
         x = 4
         for i in range(self.minimum(), self.width(), x):
             if i % 5 == 0:
                 h = 18
                 w = 1
                 z = 8
             else:
                 h = 7
                 w = 0.8
                 z = 15
             pen = QPen(QColor('#444'))
             pen.setWidthF(w)
             painter.setPen(pen)
             if self.tickPosition() in (QSlider.TicksBothSides, QSlider.TicksAbove):
                 y = self.rect().top() + z
                 painter.drawLine(x, y, x, y + h)
             if self.tickPosition() in (QSlider.TicksBothSides, QSlider.TicksBelow):
                 y = self.rect().bottom() - z
                 painter.drawLine(x, y, x, y - h)
             x += 10
     opt.subControls = QStyle.SC_SliderGroove
     painter.drawComplexControl(QStyle.CC_Slider, opt)
     opt.subControls = QStyle.SC_SliderHandle
     painter.drawComplexControl(QStyle.CC_Slider, opt)
Ejemplo n.º 3
0
 def paintEvent(self, event: QPaintEvent) -> None:
     painter = QStylePainter(self)
     opt = QStyleOptionSlider()
     self.initStyleOption(opt)
     handle = self.style.subControlRect(self.style.CC_Slider, opt,
                                        self.style.SC_SliderHandle, self)
     interval = self.tickInterval()
     if interval == 0:
         interval = self.pageStep()
     if self.tickPosition() != QSlider.NoTicks:
         for i in range(self.minimum(), self.maximum(), interval):
             x = round((((i - self.minimum()) /
                         (self.maximum() - self.minimum())) *
                        (self.width() - handle.width()) +
                        (handle.width() / 2.0))) - 1
             if i % 500000 == 0:
                 h = 12
                 z = 5
             else:
                 h = 6
                 z = 11
             painter.setPen(QColor('#484640'))
             if self.tickPosition() in (QSlider.TicksBothSides,
                                        QSlider.TicksAbove):
                 y = self.rect().top() + z
                 painter.drawLine(x, y, x, y + h)
             if self.tickPosition() in (QSlider.TicksBothSides,
                                        QSlider.TicksBelow):
                 y = self.rect().bottom() - z
                 painter.drawLine(x, y, x, y - h)
     opt.subControls = QStyle.SC_SliderGroove
     painter.drawComplexControl(QStyle.CC_Slider, opt)
     opt.subControls = QStyle.SC_SliderHandle
     painter.drawComplexControl(QStyle.CC_Slider, opt)
Ejemplo n.º 4
0
 def paintEvent(self, event: QPaintEvent) -> None:
     painter = QStylePainter(self)
     opt = QStyleOptionSlider()
     self.initStyleOption(opt)
     font = painter.font()
     font.setPixelSize(10)
     painter.setFont(font)
     if self.tickPosition() != QSlider.NoTicks:
         x = 8
         for i in range(self.minimum(), self.width(), 8):
             if i % 5 == 0:
                 h = 18
                 w = 1
                 z = 13
             else:
                 h = 8
                 w = 1
                 z = 23
             tickcolor = '#8F8F8F' if self.theme == 'dark' else '#444'
             pen = QPen(QColor(tickcolor))
             pen.setWidthF(w)
             painter.setPen(pen)
             if self.tickPosition() in (QSlider.TicksBothSides,
                                        QSlider.TicksAbove):
                 y = self.rect().top() + z
                 painter.drawLine(x, y, x, y + h)
             if self.tickPosition() in (QSlider.TicksBothSides,
                                        QSlider.TicksBelow):
                 y = self.rect().bottom() - z
                 painter.drawLine(x, y, x, y - h)
                 if self.parent.mediaAvailable and i % 15 == 0:
                     painter.setPen(Qt.white if self.theme ==
                                    'dark' else Qt.black)
                     timecode = QStyle.sliderValueFromPosition(
                         self.minimum(), self.maximum(), x - self.offset,
                         self.width() - (self.offset * 2))
                     timecode = self.parent.delta2QTime(timecode).toString(
                         self.parent.runtimeformat)
                     painter.drawText(x + 6, y + 6, timecode)
             if x + 30 > self.width():
                 break
             x += 15
     opt.subControls = QStyle.SC_SliderGroove
     painter.drawComplexControl(QStyle.CC_Slider, opt)
     for rect in self._regions:
         rect.setY(int((self.height() - self._regionHeight) / 2) - 8)
         rect.setHeight(self._regionHeight)
         if self._regions.index(rect) == self._regionSelected:
             brushcolor = QColor(150, 190, 78, 185)
         else:
             brushcolor = QColor(237, 242, 255, 185)
         painter.setBrush(brushcolor)
         painter.setPen(QColor(255, 255, 255, 170))
         painter.drawRect(rect)
     opt.subControls = QStyle.SC_SliderHandle
     painter.drawComplexControl(QStyle.CC_Slider, opt)
Ejemplo n.º 5
0
    def paintEvent(self, event):
        option = QStyleOption()
        option.initFrom(self)

        contents_rect = self.style().subElementRect(QStyle.SE_FrameContents, option, self) or self.contentsRect()  # the SE_FrameContents rect is Null unless the stylesheet defines decorations

        if self.graphStyle == self.BarStyle:
            graph_width = self.__dict__['graph_width'] = int(ceil(float(contents_rect.width()) / self.horizontalPixelsPerUnit))
        else:
            graph_width = self.__dict__['graph_width'] = int(ceil(float(contents_rect.width() - 1) / self.horizontalPixelsPerUnit) + 1)

        max_value = self.__dict__['max_value'] = max(chain([0], *(islice(reversed(graph.data), graph_width) for graph in self.graphs if graph.enabled)))

        if self.graphHeight == self.AutomaticHeight or self.graphHeight < 0:
            graph_height = self.__dict__['graph_height'] = max(self.scaler.get_height(max_value), self.minHeight)
        else:
            graph_height = self.__dict__['graph_height'] = max(self.graphHeight, self.minHeight)

        if self.graphStyle == self.BarStyle:
            height_scaling = float(contents_rect.height()) / graph_height
        else:
            height_scaling = float(contents_rect.height() - self.lineThickness) / graph_height

        painter = QStylePainter(self)
        painter.drawPrimitive(QStyle.PE_Widget, option)

        painter.setClipRect(contents_rect)

        painter.save()
        painter.translate(contents_rect.x() + contents_rect.width() - 1, contents_rect.y() + contents_rect.height() - 1)
        painter.scale(-1, -1)

        painter.setRenderHint(QStylePainter.Antialiasing, self.graphStyle != self.BarStyle)

        for graph in (graph for graph in self.graphs if graph.enabled and graph.data):
            if self.boundary is not None and 0 < self.boundary < graph_height:
                boundary_width = min(5.0/height_scaling, self.boundary-0, graph_height-self.boundary)
                pen_color = QLinearGradient(0, (self.boundary - boundary_width) * height_scaling, 0, (self.boundary + boundary_width) * height_scaling)
                pen_color.setColorAt(0, graph.color)
                pen_color.setColorAt(1, graph.over_boundary_color)
                brush_color = QLinearGradient(0, (self.boundary - boundary_width) * height_scaling, 0, (self.boundary + boundary_width) * height_scaling)
                brush_color.setColorAt(0, self.color_with_alpha(graph.color, self.fillTransparency))
                brush_color.setColorAt(1, self.color_with_alpha(graph.over_boundary_color, self.fillTransparency))
            else:
                pen_color = graph.color
                brush_color = self.color_with_alpha(graph.color, self.fillTransparency)
            dataset = islice(reversed(graph.data), graph_width)
            if self.graphStyle == self.BarStyle:
                lines = [QLineF(x*self.horizontalPixelsPerUnit, 0, x*self.horizontalPixelsPerUnit, y*height_scaling) for x, y in enumerate(dataset)]
                painter.setPen(QPen(pen_color, self.lineThickness))
                painter.drawLines(lines)
            else:
                painter.translate(0, +self.lineThickness/2 - 1)

                if self.smoothEnvelope and self.smoothFactor > 0:
                    min_value = 0
                    max_value = graph_height * height_scaling
                    cx_offset = self.horizontalPixelsPerUnit / 3.0
                    smoothness = self.smoothFactor

                    last_values = deque(3*[next(dataset) * height_scaling], maxlen=3)  # last 3 values: 0 last, 1 previous, 2 previous previous

                    envelope = QPainterPath()
                    envelope.moveTo(0, last_values[0])
                    for x, y in enumerate(dataset, 1):
                        x = x * self.horizontalPixelsPerUnit
                        y = y * height_scaling * (1 - smoothness) + last_values[0] * smoothness
                        last_values.appendleft(y)
                        c1x = x - cx_offset * 2
                        c2x = x - cx_offset
                        c1y = limit((1 + smoothness) * last_values[1] - smoothness * last_values[2], min_value, max_value)  # same gradient as previous previous value to previous value
                        c2y = limit((1 - smoothness) * last_values[0] + smoothness * last_values[1], min_value, max_value)  # same gradient as previous value to last value
                        envelope.cubicTo(c1x, c1y, c2x, c2y, x, y)
                else:
                    envelope = QPainterPath()
                    envelope.addPolygon(QPolygonF([QPointF(x*self.horizontalPixelsPerUnit, y*height_scaling) for x, y in enumerate(dataset)]))

                if self.fillEnvelope or graph.fill_envelope:
                    first_element = envelope.elementAt(0)
                    last_element = envelope.elementAt(envelope.elementCount() - 1)
                    fill_path = QPainterPath()
                    fill_path.moveTo(last_element.x, last_element.y)
                    fill_path.lineTo(last_element.x + 1, last_element.y)
                    fill_path.lineTo(last_element.x + 1, -self.lineThickness)
                    fill_path.lineTo(-self.lineThickness, -self.lineThickness)
                    fill_path.lineTo(-self.lineThickness, first_element.y)
                    fill_path.connectPath(envelope)
                    painter.fillPath(fill_path, brush_color)

                painter.strokePath(envelope, QPen(pen_color, self.lineThickness, join=Qt.RoundJoin))

                painter.translate(0, -self.lineThickness/2 + 1)

        if self.boundary is not None and self.boundaryColor:
            painter.setRenderHint(QStylePainter.Antialiasing, False)
            painter.setPen(QPen(self.boundaryColor, 1.0))
            painter.drawLine(0, self.boundary*height_scaling, contents_rect.width(), self.boundary*height_scaling)

        painter.restore()

        # queue the 'updated' signal to be emitted after returning to the main loop
        QMetaObject.invokeMethod(self, 'updated', Qt.QueuedConnection)
    def paintEvent(self, event: QPaintEvent) -> None:
        """
        Render the custom widget
        """

        painter = QStylePainter()
        painter.begin(self)

        x = 0
        y = 0
        width = self.width()

        rect = self.rect()  # type: QRect
        palette = QPalette()
        backgroundColor = palette.base().color()

        if (self.display_type == DestinationDisplayType.usage_only
                and QSplitter().lineWidth()):
            pen = painter.pen()
            painter.setPen(backgroundColor)
            painter.drawLine(rect.topLeft(), rect.topRight())
            painter.setPen(self.midPen)
            painter.drawLine(rect.bottomLeft(), rect.bottomRight())
            painter.drawLine(rect.topLeft(), rect.bottomLeft())
            if (self.container_vertical_scrollbar_visible is None
                    or not self.container_vertical_scrollbar_visible):
                painter.drawLine(rect.topRight(), rect.bottomRight())
            painter.setPen(pen)

            w = QSplitter().lineWidth()
            rect.adjust(w, w, -w, -w)

        painter.fillRect(rect, backgroundColor)

        if self.storage_space is None:
            painter.end()
            return

        highlight_menu = self.mouse_pos == DestinationDisplayMousePos.menu

        if self.display_type != DestinationDisplayType.usage_only:
            # Render the folder icon, folder name, and the menu icon
            self.deviceDisplay.paint_header(
                painter=painter,
                x=x,
                y=y,
                width=width,
                display_name=self.display_name,
                icon=self.icon,
                highlight_menu=highlight_menu,
            )
            y = y + self.deviceDisplay.dc.device_name_height

        if self.display_type != DestinationDisplayType.folder_only:
            # Render the projected storage space
            if self.display_type == DestinationDisplayType.usage_only:
                y += self.deviceDisplay.dc.padding

            photos_size_to_download, videos_size_to_download = adjusted_download_size(
                photos_size_to_download=self.photos_size_to_download,
                videos_size_to_download=self.videos_size_to_download,
                os_stat_device=self.os_stat_device,
                downloading_to=self._downloading_to,
            )

            details = make_body_details(
                bytes_total=self.storage_space.bytes_total,
                bytes_free=self.storage_space.bytes_free,
                files_to_display=self.files_to_display,
                marked=self.marked,
                photos_size_to_download=photos_size_to_download,
                videos_size_to_download=videos_size_to_download,
            )

            self.deviceDisplay.paint_body(painter=painter,
                                          x=x,
                                          y=y,
                                          width=width,
                                          details=details)

        painter.end()
Ejemplo n.º 7
0
 def renderEdges(self, painter: QStylePainter) -> None:
     rect = self.rect()
     painter.drawLine(rect.topLeft(), rect.topRight())
     painter.drawLine(rect.topLeft(), rect.bottomLeft())
Ejemplo n.º 8
0
 def renderEdges(self, painter: QStylePainter) -> None:
     rect = self.rect()
     if self.orientation() == Qt.Vertical:
         painter.drawLine(rect.topLeft(), rect.topRight())
         painter.drawLine(rect.topRight(), rect.bottomRight())
         painter.drawLine(rect.topLeft(), rect.bottomLeft())
         if not self.parent().parent().horizontalScrollBar().isVisible():
             painter.drawLine(rect.bottomLeft(), rect.bottomRight())
     else:
         painter.drawLine(rect.topLeft(), rect.bottomLeft())
         painter.drawLine(rect.bottomLeft(), rect.bottomRight())
         painter.drawLine(rect.topLeft(), rect.topRight())
         if not self.parent().parent().verticalScrollBar().isVisible():
             painter.drawLine(rect.bottomRight(), rect.topRight())
Ejemplo n.º 9
0
    def paint(self, painter, option, index):
        dlg = index.model().data(index, Qt.DisplayRole)
        painter.setRenderHint(QPainter.Antialiasing)
        color = QColor(Qt.white)
        if option.state & QStyle.State_MouseOver:
            color = QColor(variables.HIGHLIGHT_COLOR)
            painter.setPen(QPen(color))
            painter.setBrush(QBrush(color))
            painter.drawRect(option.rect)
        painter.setPen(Qt.black)
        painter.setBrush(Qt.NoBrush)
        painter.drawLine(option.rect.bottomLeft(), option.rect.bottomRight())
        doc = QTextDocument(dlg.ip)
        doc.setDocumentMargin(0)
        doc.setDefaultFont(variables.font)
        textrect = QRect(option.rect)
        textrect = textrect.marginsRemoved(variables.IP_PADDING)
        textrect.setHeight(int(doc.size().height()))
        textrect.setWidth(int(doc.size().width()))
        offset = textrect.marginsAdded(variables.IP_PADDING).height()
        painter.setPen(Qt.black)
        painter.setFont(variables.font)
        painter.translate(textrect.x(), textrect.y())
        textrectf = QRectF(textrect)
        textrectf.moveTo(0, 0)
        doc.drawContents(painter, textrectf)
        painter.translate(-textrect.x(), -textrect.y())
        string = ""
        if dlg.user == variables.USER_ME:
            string += "You: "
        print(dlg.msg)
        string += dlg.msg
        fm = QFontMetrics(variables.font_small)
        textrect = QRect(option.rect)
        textrect.moveTop(textrect.y() + offset)
        textrect = textrect.marginsRemoved(variables.MSG_PADDING)
        textrect.setHeight(fm.lineSpacing())
        spainter = QStylePainter(painter.device(), QWidget())
        spainter.setRenderHint(QPainter.Antialiasing)
        if fm.horizontalAdvance(string) > textrect.width():
            fade = QLinearGradient(variables.MSG_PADDING.left() + textrect.width()* 0.9, 0, variables.MSG_PADDING.left() + textrect.width(), 0)
            fade.setSpread(QGradient.PadSpread)
            fade.setColorAt(0, Qt.darkGray)
            fade.setColorAt(1, color)
            pal = QPalette()
            pal.setBrush(QPalette.Text, QBrush(fade))
            spainter.setFont(variables.font_small)
            spainter.drawItemText(textrect, Qt.TextSingleLine, pal, True, string, QPalette.Text)
        else:
            spainter.setPen(Qt.darkGray)
            spainter.setFont(variables.font_small)
            spainter.drawText(textrect, Qt.TextSingleLine, string)
        p1 = textrect.bottomRight() + QPoint(36, -int(textrect.height() / 2))
        if dlg.status == variables.STATUS_UNREAD:
            spainter.setPen(Qt.NoPen)
            spainter.setBrush(QColor(variables.STATUS_COLOR))
            spainter.drawEllipse(p1, 7, 7)
        elif dlg.status == variables.STATUS_UNDELIVERED:
            pen = QPen(QColor(variables.STATUS_COLOR))
            pen.setWidth(2)
            spainter.setPen(pen)
            spainter.setBrush(Qt.NoBrush)
            spainter.drawEllipse(p1, 7, 7)
            spainter.drawLine(p1, p1 + QPoint(0, -5))
            spainter.drawLine(p1, p1 + QPoint(3, 0))
        elif dlg.status == variables.STATUS_NEW:
            pen = QPen(QColor(variables.STATUS_NEW_COLOR))
            pen.setWidth(5)
            spainter.setPen(pen)
            spainter.setBrush(Qt.NoBrush)
            spainter.drawEllipse(p1, 7, 7)
        #painter.translate(-textrect.x(), -textrect.y())

        '''doc = QTextDocument(str)
Ejemplo n.º 10
0
    def paintEvent(self, event):
        option = QStyleOption()
        option.initFrom(self)

        contents_rect = self.style().subElementRect(
            QStyle.SE_FrameContents, option, self
        ) or self.contentsRect(
        )  # the SE_FrameContents rect is Null unless the stylesheet defines decorations

        if self.graphStyle == self.BarStyle:
            graph_width = self.__dict__['graph_width'] = int(
                ceil(
                    float(contents_rect.width()) /
                    self.horizontalPixelsPerUnit))
        else:
            graph_width = self.__dict__['graph_width'] = int(
                ceil(
                    float(contents_rect.width() - 1) /
                    self.horizontalPixelsPerUnit) + 1)

        max_value = self.__dict__['max_value'] = max(
            chain([0],
                  *(islice(reversed(graph.data), graph_width)
                    for graph in self.graphs if graph.enabled)))

        if self.graphHeight == self.AutomaticHeight or self.graphHeight < 0:
            graph_height = self.__dict__['graph_height'] = max(
                self.scaler.get_height(max_value), self.minHeight)
        else:
            graph_height = self.__dict__['graph_height'] = max(
                self.graphHeight, self.minHeight)

        if self.graphStyle == self.BarStyle:
            height_scaling = float(contents_rect.height()) / graph_height
        else:
            height_scaling = float(contents_rect.height() -
                                   self.lineThickness) / graph_height

        painter = QStylePainter(self)
        painter.drawPrimitive(QStyle.PE_Widget, option)

        painter.setClipRect(contents_rect)

        painter.save()
        painter.translate(contents_rect.x() + contents_rect.width() - 1,
                          contents_rect.y() + contents_rect.height() - 1)
        painter.scale(-1, -1)

        painter.setRenderHint(QStylePainter.Antialiasing,
                              self.graphStyle != self.BarStyle)

        for graph in (graph for graph in self.graphs
                      if graph.enabled and graph.data):
            if self.boundary is not None and 0 < self.boundary < graph_height:
                boundary_width = min(5.0 / height_scaling, self.boundary - 0,
                                     graph_height - self.boundary)
                pen_color = QLinearGradient(
                    0, (self.boundary - boundary_width) * height_scaling, 0,
                    (self.boundary + boundary_width) * height_scaling)
                pen_color.setColorAt(0, graph.color)
                pen_color.setColorAt(1, graph.over_boundary_color)
                brush_color = QLinearGradient(
                    0, (self.boundary - boundary_width) * height_scaling, 0,
                    (self.boundary + boundary_width) * height_scaling)
                brush_color.setColorAt(
                    0, self.color_with_alpha(graph.color,
                                             self.fillTransparency))
                brush_color.setColorAt(
                    1,
                    self.color_with_alpha(graph.over_boundary_color,
                                          self.fillTransparency))
            else:
                pen_color = graph.color
                brush_color = self.color_with_alpha(graph.color,
                                                    self.fillTransparency)
            dataset = islice(reversed(graph.data), graph_width)
            if self.graphStyle == self.BarStyle:
                lines = [
                    QLineF(x * self.horizontalPixelsPerUnit, 0,
                           x * self.horizontalPixelsPerUnit,
                           y * height_scaling) for x, y in enumerate(dataset)
                ]
                painter.setPen(QPen(pen_color, self.lineThickness))
                painter.drawLines(lines)
            else:
                painter.translate(0, +self.lineThickness / 2 - 1)

                if self.smoothEnvelope and self.smoothFactor > 0:
                    min_value = 0
                    max_value = graph_height * height_scaling
                    cx_offset = self.horizontalPixelsPerUnit / 3.0
                    smoothness = self.smoothFactor

                    last_values = deque(
                        3 * [next(dataset) * height_scaling], maxlen=3
                    )  # last 3 values: 0 last, 1 previous, 2 previous previous

                    envelope = QPainterPath()
                    envelope.moveTo(0, last_values[0])
                    for x, y in enumerate(dataset, 1):
                        x = x * self.horizontalPixelsPerUnit
                        y = y * height_scaling * (
                            1 - smoothness) + last_values[0] * smoothness
                        last_values.appendleft(y)
                        c1x = x - cx_offset * 2
                        c2x = x - cx_offset
                        c1y = limit(
                            (1 + smoothness) * last_values[1] -
                            smoothness * last_values[2], min_value, max_value
                        )  # same gradient as previous previous value to previous value
                        c2y = limit(
                            (1 - smoothness) * last_values[0] +
                            smoothness * last_values[1], min_value, max_value
                        )  # same gradient as previous value to last value
                        envelope.cubicTo(c1x, c1y, c2x, c2y, x, y)
                else:
                    envelope = QPainterPath()
                    envelope.addPolygon(
                        QPolygonF([
                            QPointF(x * self.horizontalPixelsPerUnit,
                                    y * height_scaling)
                            for x, y in enumerate(dataset)
                        ]))

                if self.fillEnvelope or graph.fill_envelope:
                    first_element = envelope.elementAt(0)
                    last_element = envelope.elementAt(envelope.elementCount() -
                                                      1)
                    fill_path = QPainterPath()
                    fill_path.moveTo(last_element.x, last_element.y)
                    fill_path.lineTo(last_element.x + 1, last_element.y)
                    fill_path.lineTo(last_element.x + 1, -self.lineThickness)
                    fill_path.lineTo(-self.lineThickness, -self.lineThickness)
                    fill_path.lineTo(-self.lineThickness, first_element.y)
                    fill_path.connectPath(envelope)
                    painter.fillPath(fill_path, brush_color)

                painter.strokePath(
                    envelope,
                    QPen(pen_color, self.lineThickness, join=Qt.RoundJoin))

                painter.translate(0, -self.lineThickness / 2 + 1)

        if self.boundary is not None and self.boundaryColor:
            painter.setRenderHint(QStylePainter.Antialiasing, False)
            painter.setPen(QPen(self.boundaryColor, 1.0))
            painter.drawLine(0, self.boundary * height_scaling,
                             contents_rect.width(),
                             self.boundary * height_scaling)

        painter.restore()

        # queue the 'updated' signal to be emitted after returning to the main loop
        QMetaObject.invokeMethod(self, 'updated', Qt.QueuedConnection)