Example #1
0
    def paint(self, painter: QPainter, option: QStyleOptionViewItem, index: QModelIndex):
        """Renders the delegate using the given painter and style option for the item specified by index.

        :param painter: A QPainter object to draw
        :param option: Options to describe what should be drawn
        :param index: _description_
        """
        if not index.isValid():
            return

        # Initialize the style options. This is not very Pythonic as it uses C++
        # references under the hood so opt is affected by the second call
        opt = QStyleOptionViewItem(option)
        self.initStyleOption(opt, index)

        # Standard setup, paint, restore operation
        painter.save()
        try:
            painter.setClipRect(opt.rect)
            foreground_colour, background_colour = index.data(Qt.ForegroundRole), index.data(Qt.BackgroundRole)
            if foreground_colour is not None:
                painter.setPen(foreground_colour)
            if background_colour is not None:
                painter.fillRect(option.rect, background_colour)
            padding = self._padding
            opt.rect = option.rect.adjusted(padding, padding, -padding, -padding)
            painter.drawText(opt.rect, int(Qt.AlignLeft | Qt.AlignVCenter),
                             opt.fontMetrics.elidedText(opt.text, Qt.ElideRight, opt.rect.width()))
        finally:
            painter.restore()
Example #2
0
    def paint(self, painter, option, index):
        options = QStyleOptionViewItem(option)
        self.initStyleOption(options, index)

        style = QApplication.style() if options.widget is None else options.widget.style()

        doc = QTextDocument()
        doc.setDocumentMargin(self._margin)
        doc.setHtml(options.text)

        options.text = ""
        style.drawControl(QStyle.CE_ItemViewItem, options, painter)

        ctx = QAbstractTextDocumentLayout.PaintContext()

        textRect = style.subElementRect(QStyle.SE_ItemViewItemText, options)
        painter.save()
        if style.objectName() == "oxygen":
            painter.translate(textRect.topLeft() + QPoint(5, -9))
        else:
            painter.translate(textRect.topLeft())
            painter.setClipRect(textRect.translated(-textRect.topLeft()))
        doc.documentLayout().draw(painter, ctx)

        painter.restore()
Example #3
0
    def paint(self, painter, option, index):
        options = QStyleOptionViewItem(option)
        self.initStyleOption(options, index)

        style = (QApplication.style() if options.widget is None
                 else options.widget.style())

        doc = QTextDocument()
        doc.setDocumentMargin(self._margin)
        doc.setHtml(options.text)

        options.text = ""
        style.drawControl(QStyle.CE_ItemViewItem, options, painter)

        ctx = QAbstractTextDocumentLayout.PaintContext()

        textRect = style.subElementRect(QStyle.SE_ItemViewItemText, options)
        painter.save()

        # Adjustments for the file switcher
        if hasattr(options.widget, 'files_list'):
            if style.objectName() in ['oxygen', 'qtcurve', 'breeze']:
                if options.widget.files_list:
                    painter.translate(textRect.topLeft() + QPoint(4, -9))
                else:
                    painter.translate(textRect.topLeft())
            else:
                if options.widget.files_list:
                    painter.translate(textRect.topLeft() + QPoint(4, 4))
                else:
                    painter.translate(textRect.topLeft() + QPoint(2, 4))
        else:
            painter.translate(textRect.topLeft() + QPoint(0, -3))
        doc.documentLayout().draw(painter, ctx)
        painter.restore()
Example #4
0
    def paint(self, painter, option, index):
        options = QStyleOptionViewItem(option)
        self.initStyleOption(options, index)

        style = (QApplication.style()
                 if options.widget is None else options.widget.style())

        doc = QTextDocument()
        doc.setDocumentMargin(self._margin)
        doc.setHtml(options.text)

        options.text = ""
        style.drawControl(QStyle.CE_ItemViewItem, options, painter)

        ctx = QAbstractTextDocumentLayout.PaintContext()

        textRect = style.subElementRect(QStyle.SE_ItemViewItemText, options)
        painter.save()

        # Adjustments for the file switcher
        if hasattr(options.widget, 'files_list'):
            if style.objectName() in ['oxygen', 'qtcurve', 'breeze']:
                if options.widget.files_list:
                    painter.translate(textRect.topLeft() + QPoint(4, -9))
                else:
                    painter.translate(textRect.topLeft())
            else:
                if options.widget.files_list:
                    painter.translate(textRect.topLeft() + QPoint(4, 4))
                else:
                    painter.translate(textRect.topLeft() + QPoint(2, 4))
        else:
            painter.translate(textRect.topLeft() + QPoint(0, -3))
        doc.documentLayout().draw(painter, ctx)
        painter.restore()
Example #5
0
 def _style_option(self, index):
     """Get default style option for index"""
     option = QStyleOptionViewItem()
     option.font = self.font()
     option.rect = self.visualRect(index)
     option.state = QStyle.State_Enabled
     return option
Example #6
0
    def paint(
        self,
        painter: QPainter,
        style: QStyleOptionViewItem,
        model: QModelIndex,
    ):
        style2 = QStyleOptionViewItem(style)

        cbar_rect = QRect(
            style.rect.x(),
            style.rect.y() + PADDING,
            style.rect.width() - TEXT_WIDTH,
            style.rect.height() - 2 * PADDING,
        )
        text_rect = QRect(
            style.rect.width() - TEXT_WIDTH,
            style.rect.y() + PADDING,
            style.rect.width(),
            style.rect.height() - 2 * PADDING,
        )
        style2.rect = text_rect
        super().paint(painter, style2, model)
        cbar = make_colorbar(ensure_colormap(model.data()), (18, 100))
        image = QImage(
            cbar,
            cbar.shape[1],
            cbar.shape[0],
            QImage.Format_RGBA8888,
        )
        painter.drawImage(cbar_rect, image)
Example #7
0
    def paint(self, painter, option, index):
        options = QStyleOptionViewItem(option)
        self.initStyleOption(options, index)

        style = (QApplication.style()
                 if options.widget is None else options.widget.style())

        doc = QTextDocument()
        doc.setDocumentMargin(self._margin)
        doc.setHtml(options.text)

        options.text = ""
        style.drawControl(QStyle.CE_ItemViewItem, options, painter)

        ctx = QAbstractTextDocumentLayout.PaintContext()

        textRect = style.subElementRect(QStyle.SE_ItemViewItemText, options)
        painter.save()
        if style.objectName() == 'oxygen':
            painter.translate(textRect.topLeft() + QPoint(5, -9))
        else:
            painter.translate(textRect.topLeft())
            painter.setClipRect(textRect.translated(-textRect.topLeft()))
        doc.documentLayout().draw(painter, ctx)

        painter.restore()
Example #8
0
    def paint(self, painter, option, index):
        options = QStyleOptionViewItem(option)
        self.initStyleOption(options, index)

        style = (QApplication.style()
                 if options.widget is None else options.widget.style())

        doc = QTextDocument()
        text = options.text
        doc.setHtml(text)
        doc.setDocumentMargin(0)

        # This needs to be an empty string to avoid the overlapping the
        # normal text of the QTreeWidgetItem
        options.text = ""
        style.drawControl(QStyle.CE_ItemViewItem, options, painter)

        ctx = QAbstractTextDocumentLayout.PaintContext()

        textRect = style.subElementRect(QStyle.SE_ItemViewItemText, options,
                                        None)
        painter.save()

        painter.translate(textRect.topLeft())
        painter.setClipRect(textRect.translated(-textRect.topLeft()))
        doc.documentLayout().draw(painter, ctx)
        painter.restore()
Example #9
0
    def test_custom_eliding_delegate_respects_padding(self):
        padding = 3
        delegate = CustomTextElidingDelegate(padding)
        painter = mock.MagicMock(spec=QPainter)
        # we cannot mock the style & index as they are passed to a C++ type that expects real types
        style, model = QStyleOptionViewItem(), QStandardItemModel(1, 1)
        style.rect = QRect(0, 0, 99,
                           29)  # give a non-zero sized rectangle to paint in
        text = str(math.pi)
        model.setData(model.index(0, 0), text, Qt.DisplayRole)

        delegate.paint(painter, style, model.index(0, 0))

        painter.save.assert_called_once()
        painter.setPen.assert_not_called()
        painter.fillRect.assert_not_called()
        painter.drawText.assert_called_once()
        painter.restore.assert_called_once()

        # first call and second argument is the text that will be painted
        # the exact text depends on the font metric so we have a looser requirement
        # for matching
        drawn_text = painter.drawText.call_args[0][2]
        self.assertTrue(drawn_text.startswith("3.141592"))
        # Qt uses the 'horizontal ellipsis' unicode symbol for ellision.
        # To avoid confusion with it look like 3 separate '.' characters in code
        # we use the unicode codepoint directly
        self.assertTrue(drawn_text.endswith(b"\xe2\x80\xa6".decode("utf-8")))
Example #10
0
    def _draw_fold_indicator(self, top, mouse_over, collapsed, painter):
        """
        Draw the fold indicator/trigger (arrow).

        :param top: Top position
        :param mouse_over: Whether the mouse is over the indicator
        :param collapsed: Whether the trigger is collapsed or not.
        :param painter: QPainter
        """
        rect = QRect(0, top, self.sizeHint().width(), self.sizeHint().height())
        if self._native_icons:
            opt = QStyleOptionViewItem()

            opt.rect = rect
            opt.state = (QStyle.State_Active | QStyle.State_Item
                         | QStyle.State_Children)
            if not collapsed:
                opt.state |= QStyle.State_Open
            if mouse_over:
                opt.state |= (QStyle.State_MouseOver | QStyle.State_Enabled
                              | QStyle.State_Selected)
                opt.palette.setBrush(QPalette.Window,
                                     self.palette().highlight())
            opt.rect.translate(-2, 0)
            self.style().drawPrimitive(QStyle.PE_IndicatorBranch, opt, painter,
                                       self)
        else:
            index = 0
            if not collapsed:
                index = 2
            if mouse_over:
                index += 1
            ima.icon(self._indicators_icons[index]).paint(painter, rect)
Example #11
0
    def test_custom_eliding_delegate_respects_forgeround_color(self):
        padding = 3
        delegate = CustomTextElidingDelegate(padding)
        painter = mock.MagicMock(spec=QPainter)
        # we cannot mock the style & index as they are passed to a C++ type that expects real types
        style, model = QStyleOptionViewItem(), QStandardItemModel(1, 1)
        style.rect = QRect(0, 0, 99,
                           29)  # give a non-zero sized rectangle to paint in
        text, foreground = str(math.pi), QColor(10, 10, 10)
        model.setData(model.index(0, 0), text, Qt.DisplayRole)
        model.setData(model.index(0, 0), foreground, Qt.ForegroundRole)

        delegate.paint(painter, style, model.index(0, 0))

        painter.setPen.assert_called_once_with(foreground)
        painter.fillRect.assert_not_called()
    def paint(self, painter, option, index):
        """
        Overrides the selection highlight color.

        https://www.qtcentre.org/threads/41299-How-to-Change-QTreeView-highlight-color
        Note: this can actually do alot more than that with the QPalette...
            which is something I should learn how to use apparently...

        """
        from qtpy.QtGui import QPalette
        item = index.internalPointer()
        new_option = QStyleOptionViewItem(option)
        brush = QBrush()
        if item.isEnabled():
            color = QColor(*iColor["rgba_text"])
        else:
            color = QColor(*iColor["rgba_text_disabled"])
        # TODO highlight selection color???
        # why did I move this here?
        brush.setColor(color)

        # brush2 = QBrush(QColor(0, 255, 0, 128))
        new_option.palette.setBrush(QPalette.Normal, QPalette.HighlightedText,
                                    brush)
        # new_option.palette.setBrush(QPalette.Normal, QPalette.Highlight, brush2)

        QStyledItemDelegate.paint(self, painter, new_option, index)

        # if option.state == QStyle.State_Selected:
        #     brush2 = QBrush(QColor(0, 255, 255, 128))
        return
Example #13
0
 def sizeHint(self, option, index):
     options = QStyleOptionViewItem(option)
     self.initStyleOption(options, index)
     doc = QTextDocument()
     doc.setHtml(options.text)
     doc.setTextWidth(options.rect.width())
     size = QSize(int(doc.idealWidth()), int(doc.size().height()))
     return size
Example #14
0
    def sizeHint(self, option, index):
        options = QStyleOptionViewItem(option)
        self.initStyleOption(options, index)

        doc = QTextDocument()
        doc.setHtml(options.text)

        return QSize(doc.idealWidth(), doc.size().height() - 2)
Example #15
0
    def test_custom_eliding_delegate_respects_background_color(self):
        padding = 3
        delegate = CustomTextElidingDelegate(padding)
        painter = mock.MagicMock(spec=QPainter)
        # we cannot mock the style & index as they are passed to a C++ type that expects real types
        style, model = QStyleOptionViewItem(), QStandardItemModel(1, 1)
        style.rect = QRect(0, 0, 99,
                           29)  # give a non-zero sized rectangle to paint in
        text, background = str(math.pi), QColor(5, 5, 5)
        model.setData(model.index(0, 0), text, Qt.DisplayRole)
        model.setData(model.index(0, 0), background, Qt.BackgroundRole)

        delegate.paint(painter, style, model.index(0, 0))

        painter.setPen.assert_not_called()
        painter.fillRect.assert_called_once()
        # the background color object seems different but we only care about value equality
        self.assertEqual(background, painter.fillRect.call_args[0][1])
Example #16
0
    def _prepare_text_document(self, option, index):
        # This logic must be shared between paint and sizeHint for consistency
        options = QStyleOptionViewItem(option)
        self.initStyleOption(options, index)

        doc = QTextDocument()
        doc.setDocumentMargin(self._margin)
        doc.setHtml(options.text)
        return options, doc
Example #17
0
    def paint(self, painter, option, index):
        options = QStyleOptionViewItem(option)
        self.initStyleOption(options, index)
        style = (QApplication.style()
                 if options.widget is None else options.widget.style())

        # Set background color for selected and hovered items.
        # Inspired by:
        # - https://stackoverflow.com/a/43253004/438386
        # - https://stackoverflow.com/a/27274233/438386

        # This is commented for now until we find a way to correctly colorize
        # the entire line with a single color.
        # if options.state & QStyle.State_Selected:
        #     # This only applies when the selected item doesn't have focus
        #     if not (options.state & QStyle.State_HasFocus):
        #         options.palette.setBrush(
        #             QPalette.Highlight,
        #             QBrush(self._background_color)
        #         )

        if options.state & QStyle.State_MouseOver:
            painter.fillRect(option.rect, self._background_color)

        # Set text
        doc = QTextDocument()
        text = options.text
        doc.setHtml(text)
        doc.setDocumentMargin(0)

        # This needs to be an empty string to avoid overlapping the
        # normal text of the QTreeWidgetItem
        options.text = ""
        style.drawControl(QStyle.CE_ItemViewItem, options, painter)

        ctx = QAbstractTextDocumentLayout.PaintContext()

        textRect = style.subElementRect(QStyle.SE_ItemViewItemText, options,
                                        None)
        painter.save()

        painter.translate(textRect.topLeft() + QPoint(0, 4))
        doc.documentLayout().draw(painter, ctx)
        painter.restore()
Example #18
0
    def test_custom_eliding_delegate_does_nothing_for_invalid_indices(self):
        delegate = CustomTextElidingDelegate(padding=5)
        painter = mock.MagicMock(spec=QPainter)
        # we cannot mock the style &index as they are passed to a C++ type that expects real types
        style, invalid_index = QStyleOptionViewItem(), QModelIndex()

        delegate.paint(painter, style, invalid_index)

        painter.save.assert_not_called()
        painter.drawText.assert_not_called()
        painter.restore.assert_not_called()
Example #19
0
    def _draw_fold_indicator(self, top, mouse_over, collapsed, painter):
        """
        Draw the fold indicator/trigger (arrow).

        :param top: Top position
        :param mouse_over: Whether the mouse is over the indicator
        :param collapsed: Whether the trigger is collapsed or not.
        :param painter: QPainter
        """
        rect = QRect(0, top, self.sizeHint().width(),
                            self.sizeHint().height())
        if self._native_icons:
            opt = QStyleOptionViewItem()

            opt.rect = rect
            opt.state = (QStyle.State_Active |
                         QStyle.State_Item |
                         QStyle.State_Children)
            if not collapsed:
                opt.state |= QStyle.State_Open
            if mouse_over:
                opt.state |= (QStyle.State_MouseOver |
                              QStyle.State_Enabled |
                              QStyle.State_Selected)
                opt.palette.setBrush(QPalette.Window,
                                     self.palette().highlight())
            opt.rect.translate(-2, 0)
            self.style().drawPrimitive(QStyle.PE_IndicatorBranch,
                                       opt, painter, self)
        else:
            index = 0
            if not collapsed:
                index = 2
            if mouse_over:
                index += 1
            ima.icon(self._indicators_icons[index]).paint(painter, rect)
Example #20
0
 def initStyleOption(self, option: QStyleOptionViewItem,
                     index: QModelIndex) -> None:
     super().initStyleOption(option, index)
     option.textElideMode = Qt.ElideMiddle
 def paint(self, painter, options, index):
     new_options = QStyleOptionViewItem(options)
     text_color = self.get_text_color(index.data())
     new_options.palette.setColor(QPalette.Text, text_color)
     super(StatusItemDelegate, self).paint(painter, new_options, index)