def __init__(self, *args, **kwargs): self.__selected = False self.__palette = QPalette() self.__content = "" #: The cached text background shape when this item is selected self.__cachedBackgroundPath = None # type: Optional[QPainterPath] self.__styleState = QStyle.State(0) super().__init__(*args, **kwargs) layout = self.document().documentLayout() layout.update.connect(self.__onLayoutChanged)
def __updateAnchors(self): state = QStyle.State(0) if self.hover: state |= QStyle.State_MouseOver if self.isSelected() or self.__isSelectedImplicit(): state |= QStyle.State_Selected if self.sinkAnchor is not None: self.sinkAnchor.indicator.setStyleState(state) self.sinkAnchor.indicator.setLinkState(self.__state) if self.sourceAnchor is not None: self.sourceAnchor.indicator.setStyleState(state) self.sourceAnchor.indicator.setLinkState(self.__state)
def paint(self, painter, option, widget=None): # type: (QPainter, QStyleOptionGraphicsItem, Optional[QWidget]) -> None """ Paint the shape and a progress meter. """ # Let the default implementation draw the shape if option.state & QStyle.State_Selected: # Prevent the default bounding rect selection indicator. option.state = QStyle.State(option.state ^ QStyle.State_Selected) super().paint(painter, option, widget) if self.__progress >= 0: # Draw the progress meter over the shape. # Set the clip to shape so the meter does not overflow the shape. painter.save() painter.setClipPath(self.shape(), Qt.ReplaceClip) color = self.palette.color(QPalette.ButtonText) pen = QPen(color, 5) painter.setPen(pen) painter.setRenderHints(QPainter.Antialiasing) span = max(1, int(self.__progress * 57.60)) painter.drawArc(self.__shapeRect, 90 * 16, -span) painter.restore()
def initStyleOptionForIndex(self, option: QStyleOptionHeader, logicalIndex: int) -> None: """ Similar to initStyleOptionForIndex in Qt 6.0 with the difference that `isSectionSelected` is not used, only `sectionIntersectsSelection` is used (isSectionSelected will scan the entire model column/row when the whole column/row is selected). """ hover = self.logicalIndexAt(self.mapFromGlobal(QCursor.pos())) pressed = self.__pressed if self.highlightSections(): is_selected = self.__sectionIntersectsSelection else: is_selected = lambda _: False state = QStyle.State_None if self.isEnabled(): state |= QStyle.State_Enabled if self.window().isActiveWindow(): state |= QStyle.State_Active if self.sectionsClickable(): if logicalIndex == hover: state |= QStyle.State_MouseOver if logicalIndex == pressed: state |= QStyle.State_Sunken if self.highlightSections(): if is_selected(logicalIndex): state |= QStyle.State_On if self.isSortIndicatorShown() and \ self.sortIndicatorSection() == logicalIndex: option.sortIndicator = ( QStyleOptionHeader.SortDown if self.sortIndicatorOrder() == Qt.AscendingOrder else QStyleOptionHeader.SortUp) style = self.style() model = self.model() orientation = self.orientation() textAlignment = model.headerData(logicalIndex, self.orientation(), Qt.TextAlignmentRole) defaultAlignment = self.defaultAlignment() textAlignment = (textAlignment if isinstance(textAlignment, int) else defaultAlignment) option.section = logicalIndex option.state = QStyle.State(int(option.state) | int(state)) option.textAlignment = Qt.Alignment(int(textAlignment)) option.iconAlignment = Qt.AlignVCenter text = model.headerData(logicalIndex, self.orientation(), Qt.DisplayRole) text = str(text) if text is not None else "" option.text = text icon = model.headerData(logicalIndex, self.orientation(), Qt.DecorationRole) try: option.icon = QIcon(icon) except (TypeError, ValueError): # pragma: no cover pass margin = 2 * style.pixelMetric(QStyle.PM_HeaderMargin, None, self) headerArrowAlignment = style.styleHint(QStyle.SH_Header_ArrowAlignment, None, self) isHeaderArrowOnTheSide = headerArrowAlignment & Qt.AlignVCenter if self.isSortIndicatorShown() and \ self.sortIndicatorSection() == logicalIndex \ and isHeaderArrowOnTheSide: margin += style.pixelMetric(QStyle.PM_HeaderMarkSize, None, self) if not option.icon.isNull(): margin += style.pixelMetric(QStyle.PM_SmallIconSize, None, self) margin += style.pixelMetric(QStyle.PM_HeaderMargin, None, self) if self.textElideMode() != Qt.ElideNone: elideMode = self.textElideMode() if hasattr(option, 'textElideMode'): # Qt 6.0 option.textElideMode = elideMode # pragma: no cover else: option.text = option.fontMetrics.elidedText( option.text, elideMode, option.rect.width() - margin) foregroundBrush = model.headerData(logicalIndex, orientation, Qt.ForegroundRole) try: foregroundBrush = QBrush(foregroundBrush) except (TypeError, ValueError): pass else: option.palette.setBrush(QPalette.ButtonText, foregroundBrush) backgroundBrush = model.headerData(logicalIndex, orientation, Qt.BackgroundRole) try: backgroundBrush = QBrush(backgroundBrush) except (TypeError, ValueError): pass else: option.palette.setBrush(QPalette.Button, backgroundBrush) option.palette.setBrush(QPalette.Window, backgroundBrush) # the section position visual = self.visualIndex(logicalIndex) assert visual != -1 first = self.__isFirstVisibleSection(visual) last = self.__isLastVisibleSection(visual) if first and last: option.position = QStyleOptionHeader.OnlyOneSection elif first: option.position = QStyleOptionHeader.Beginning elif last: option.position = QStyleOptionHeader.End else: option.position = QStyleOptionHeader.Middle option.orientation = orientation # the selected position (in QHeaderView this is always computed even if # highlightSections is False). if self.highlightSections(): previousSelected = is_selected(self.logicalIndex(visual - 1)) nextSelected = is_selected(self.logicalIndex(visual + 1)) else: previousSelected = nextSelected = False if previousSelected and nextSelected: option.selectedPosition = QStyleOptionHeader.NextAndPreviousAreSelected elif previousSelected: option.selectedPosition = QStyleOptionHeader.PreviousIsSelected elif nextSelected: option.selectedPosition = QStyleOptionHeader.NextIsSelected else: option.selectedPosition = QStyleOptionHeader.NotAdjacent