def drawContents(self, painter): """ Reimplementation of drawContents to limit the drawing inside `textRext`. """ painter.setPen(self.__color) painter.setFont(self.font()) if self.__textRect: rect = self.__textRect else: rect = self.rect().adjusted(5, 5, -5, -5) if Qt.mightBeRichText(self.__message): doc = QTextDocument() doc.setHtml(self.__message) doc.setTextWidth(rect.width()) cursor = QTextCursor(doc) cursor.select(QTextCursor.Document) fmt = QTextBlockFormat() fmt.setAlignment(self.__alignment) cursor.mergeBlockFormat(fmt) painter.save() painter.translate(rect.topLeft()) doc.drawContents(painter) painter.restore() else: painter.drawText(rect, self.__alignment, self.__message)
def pixmap(cursor, num_lines=6, scale=0.8): """Return a QPixmap displaying the selected lines of the document. If the cursor has no selection, num_lines are drawn. By default the text is drawn 0.8 * the normal font size. You can change that by supplying the scale parameter. """ block = cursor.document().findBlock(cursor.selectionStart()) c2 = QTextCursor(block) if cursor.hasSelection(): c2.setPosition(cursor.selectionEnd(), QTextCursor.KeepAnchor) c2.movePosition(QTextCursor.EndOfBlock, QTextCursor.KeepAnchor) else: c2.movePosition(QTextCursor.NextBlock, QTextCursor.KeepAnchor, num_lines) data = textformats.formatData('editor') doc = QTextDocument() font = QFont(data.font) font.setPointSizeF(font.pointSizeF() * scale) doc.setDefaultFont(font) doc.setPlainText(c2.selection().toPlainText()) if metainfo.info(cursor.document()).highlighting: highlighter.highlight(doc, state=tokeniter.state(block)) size = doc.size().toSize() + QSize(8, -4) pix = QPixmap(size) pix.fill(data.baseColors['background']) doc.drawContents(QPainter(pix)) return pix
def stamp_image(image, expression_str, position, feature): painter = QPainter(image) data = roam.api.utils.replace_expression_placeholders(expression_str, feature) if not data: return image data = data.replace(r"\n", "<br>") style = """ body { color: yellow; } """ doc = QTextDocument() doc.setDefaultStyleSheet(style) data = "<body>{}</body>".format(data) doc.setHtml(data) point = QPointF(20, 20) # Wrap the text so we don't go crazy if doc.size().width() > 300: doc.setTextWidth(300) if position == "top-left": point = QPointF(20, 20) elif position == "top-right": x = image.width() - 20 - doc.size().width() point = QPointF(x, 20) elif position == "bottom-left": point = QPointF(20, image.height() - 20 - doc.size().height()) elif position == "bottom-right": x = image.width() - 20 - doc.size().width() y = image.height() - 20 - doc.size().height() point = QPointF(x, y) painter.translate(point) doc.drawContents(painter) return image
def paint(self, painter, option, index): text = index.model().data(index, Qt.DisplayRole) document = QTextDocument() # metrics = QFontMetrics(document.defaultFont()) metrics = painter.fontMetrics() # font = QFont() # font.setPointSize(12) document.setDefaultFont(G.entriesFont) if index.column() == 0: document.setTextWidth(69) elif index.column() == 1: document.setTextWidth(514) if option.state & QStyle.State_Selected: document.setHtml("<b bgcolor=#E6E600> <font size={} font color={}>{}" "</font></b>".format("2", G.selectionColor, text)) else: w = metrics.boundingRect('W').width() # print(w) txt = text[0:(514*4)//w] document.setHtml("<p align (center) bgcolor=white> <font size={} " "font color={}>{}" "</font></p>".format("2", "black", txt)) painter.save() painter.translate(option.rect.x(), option.rect.y()) document.drawContents(painter) painter.restore()
def get_pixmap(self, txt, hl, rect): """ store pixmap cache. Switch to LRU cache if too much memory is used. """ if (hl, txt) in HexItemDelegate.pixcache: return HexItemDelegate.pixcache[(hl, txt)] # FIXME use correct size? on non-hdpi screen, 15x22 real size pixmap = QPixmap(rect.width(), rect.height()) if hl: # Carefully measured using the gimp. YMMV. # Used to be done using proper Qt API calls before pixmap cache was # introduced in revision 731562b77ece9301f61de6626432891dfc34ba91 pixmap.fill(QColor.fromRgb(48, 140, 198)) else: pixmap.fill(Qt.white) doc = QTextDocument() doc.setHtml(txt) painter = QPainter() painter.begin(pixmap) doc.drawContents(painter) painter.end() HexItemDelegate.pixcache[txt] = pixmap return pixmap
def paint(self, painter, option, widget): font = painter.font() font.setPointSize(self.textSize) painter.setFont(font) painter.translate(QPointF(self.pos().x(), self.pos().y())) td = QTextDocument() td.setHtml(self.text) td.drawContents(painter) super().paint(painter, option, widget)
def paint(self, painter, option, index): text = index.data() doc = QTextDocument() doc.setHtml(text) doc.setTextWidth(option.rect.width()) painter.save() painter.translate(option.rect.x(), option.rect.y()) doc.drawContents(painter) painter.restore() index.model().setData(index, option.rect.width(), Qt.UserRole + 1337)
class SuggestionsDelegate(QStyledItemDelegate): def __init__(self, parent=None): super().__init__(parent=parent) self._doc = QTextDocument() self._translation_char_format = QTextCharFormat() self._strokes_char_format = QTextCharFormat() self._strokes_char_format.font().setStyleHint(QFont.Monospace) @property def text_font(self): return self._translation_char_format.font() @text_font.setter def text_font(self, font): self._translation_char_format.setFont(font) @property def strokes_font(self): return self._strokes_char_format.font() @strokes_font.setter def strokes_font(self, font): self._strokes_char_format.setFont(font) def _format_suggestion(self, index): suggestion = index.data(Qt.DisplayRole) self._doc.clear() cursor = QTextCursor(self._doc) cursor.setCharFormat(self._translation_char_format) cursor.insertText(escape_translation(suggestion.text) + ':') if not suggestion.steno_list: cursor.insertText(' ' + NO_SUGGESTIONS_STRING) return for strokes_list in suggestion.steno_list[:MAX_SUGGESTIONS_COUNT]: cursor.insertBlock() cursor.setCharFormat(self._strokes_char_format) cursor.insertText(' ' + '/'.join(strokes_list)) def paint(self, painter, option, index): painter.save() if option.state & QStyle.State_Selected: painter.fillRect(option.rect, option.palette.highlight()) text_color = option.palette.highlightedText() else: text_color = option.palette.text() self._translation_char_format.setForeground(text_color) self._strokes_char_format.setForeground(text_color) painter.translate(option.rect.topLeft()) self._format_suggestion(index) self._doc.drawContents(painter) painter.restore() def sizeHint(self, option, index): self._format_suggestion(index) return self._doc.size().toSize()
def paint(self, painter, option, index): text = index.model().data(index, Qt.DisplayRole) palette = QApplication.palette() document = QTextDocument() if option.state & QStyle.State_Selected: document.setHtml("<p <center <font size={} font color={}>{}" "</font></center></p>".format( "5", palette.highlightedText().color().name(), text)) else: document.setPlainText(text) painter.save() painter.translate(option.rect.x(), option.rect.y()) document.drawContents(painter) painter.restore()
def paintEvent(self, e): painter = QPainter(self) painter.drawText(100, 100, "Hello PyQt5 App Development") rect = QRectF(100, 150, 250, 25) painter.drawRect(rect) painter.drawText(rect, Qt.AlignCenter, "Hello World") document = QTextDocument() rect2 = QRectF(0, 0, 250, 250) document.setTextWidth(rect2.width()) document.setHtml("<b>Python GUI</b> <i>Development</i> <font size='10' color='red'>Complete Series</font>") document.drawContents(painter, rect2)
def paint(self, painter, option, index): text = index.model().data(index, Qt.DisplayRole) document = QTextDocument() if index.column() == 0: document.setTextWidth(160) elif index.column() == 1: document.setTextWidth(100) if option.state & QStyle.State_Selected: document.setHtml("<b style=background-color:{}> <font size={} font color={}>{}" "</font></b>".format(G.dayNumberBkgnd, "3", G.selectionColor, text)) else: document.setHtml(text) painter.save() painter.translate(option.rect.x(), option.rect.y()) document.drawContents(painter) painter.restore()
def paint(self, painter, option, index): text = index.model().data(index, Qt.DisplayRole) palette = QApplication.palette() document = QTextDocument() # if option.state & QStyle.State_Selected: # document.setHtml("<p <center <font color={}>{}</font></center></p>".format( # palette.highlightedText().color().name(), text)) # else: document.setPlainText(text) if index.column() == 1: document.setTextWidth(350) elif index.column() == 2: document.setTextWidth(150) to = QTextOption() painter.save() painter.translate(option.rect.x(), option.rect.y()) document.drawContents(painter) painter.restore()
def paint(self, painter, option, index): text = index.model().data(index, Qt.DisplayRole) palette = QApplication.palette() document = QTextDocument() document.setDefaultFont(option.font) if option.state & QStyle.State_Selected: document.setHtml("<font color={0}>{1}</font>".format( palette.highlightedText().color().name(), text)) else: document.setHtml(text) painter.save() color = (palette.highlight().color() if option.state & QStyle.State_Selected else QColor(index.model().data( index, Qt.BackgroundColorRole))) painter.fillRect(option.rect, color) painter.translate(option.rect.x(), option.rect.y()) document.drawContents(painter) painter.restore()
def paint(self, painter, option, index): text = index.model().data(index, Qt.DisplayRole) document = QTextDocument() column = index.column() row = index.row() document.setTextWidth(115) if row % 2 == 0: document.setHtml( "<p style=margin-left:0; style=background-color:{}; style=" "color:{}><center <b <font size={} >{}</font>" "</b></center></p>".format(G.dayNumberBkgnd, G.dayNumberColor, "3", text)) elif option.state & QStyle.State_Selected: document.setHtml("<b> <font size={} font color={}>{}" "</font></b>".format("3", G.selectionColor, text)) else: document.setHtml(text) painter.save() painter.translate(option.rect.x(), option.rect.y()) document.drawContents(painter) painter.restore()
def paint(self, painter, option, index): if index.column() == DESCRIPTION: text = str(index.model().data(index)) palette = QApplication.palette() document = QTextDocument() document.setDefaultFont(option.font) if option.state & QStyle.State_Selected: # document.setHtml("<font color={0}>{1}</font>".format("#FF0000",text)) document.setHtml("<font color={0}>{1}</font>".format( palette.highlightedText().color().name(), text)) else: document.setHtml(text) color = (palette.highlight().color() if option.state & QStyle.State_Selected else QColor(index.model().data( index, Qt.BackgroundColorRole))) # print(palette.highlight().color().name()) painter.save() painter.fillRect(option.rect, color) painter.translate(option.rect.x(), option.rect.y()) document.drawContents(painter) painter.restore() else: QStyledItemDelegate.paint(self, painter, option, index)
def render(self, renderer): if not self._shader: # We now misuse the platform shader, as it actually supports textures self._shader = OpenGL.getInstance().createShaderProgram( Resources.getPath(Resources.Shaders, "platform.shader")) # Set the opacity to 0, so that the template is in full control. self._shader.setUniformValue("u_opacity", 0) self._texture = OpenGL.getInstance().createTexture() document = QTextDocument() document.setHtml( self._getFilledTemplate(self._display_data, self._template)) texture_image = QImage(self._texture_width, self._texture_height, QImage.Format_ARGB32) texture_image.fill(Qt.transparent) painter = QPainter(texture_image) document.drawContents( painter, QRectF(0., 0., self._texture_width, self._texture_height)) painter.end() self._texture.setImage(texture_image) self._shader.setTexture(0, self._texture) node_position = self._target_node.getWorldPosition() position_matrix = Matrix() position_matrix.setByTranslation(node_position) camera_orientation = self._scene.getActiveCamera().getOrientation( ).toMatrix() renderer.queueNode(self._scene.getRoot(), shader=self._shader, transparent=True, mesh=self._billboard_mesh.getTransformed( position_matrix.multiply(camera_orientation)), sort=self._target_node.getDepth()) return True # This node does it's own rendering.
def paint_strip_box(parent_widget, painter, strip, rect): acft = strip.linkedAircraft() ### LINE 1 scs = strip.callsign(fpl=True) acs = None if acft == None else acft.xpdrCallsign() cs = some(scs, acs) if settings.strip_CPDLC_integration and cs != None and (acs == None or acs == scs): sdl = env.cpdlc.currentDataLink(cs) else: sdl = None ## Decorated callsign section callsign_section = '' # handover from fromATC = strip.lookup(received_from_detail) if fromATC != None: callsign_section += fromATC + ' >> ' # callsign(s) if sdl != None: callsign_section += '⚡ ' if sdl.status( ) == ConnectionStatus.OK else '[⚡] ' callsign_section += '<strong>%s</strong>' % some(cs, '?') if scs != None and acs != None and scs != acs: # callsign conflict with XPDR callsign_section += ' <strong>(%s)</strong>' % acs if strip.lookup(FPL.COMMENTS) != None: callsign_section += '*' # handover to toATC = strip.lookup(sent_to_detail) if toATC != None: callsign_section += ' >> ' + toATC if strip.lookup(duplicate_callsign_detail): # duplicate callsign warning callsign_section += ' !!dup' line1_sections = [callsign_section] ## Wake turb. cat. / aircraft type atyp = None if acft == None else acft.xpdrAcftType() typesec = some(strip.lookup(FPL.ACFT_TYPE, fpl=True), some(atyp, '')) wtc = strip.lookup(FPL.WTC, fpl=True) if wtc != None: typesec += '/%s' % wtc line1_sections.append(typesec) ## Optional sections # transponder code assSQ = strip.lookup(assigned_SQ_detail) if assSQ != None: if acft == None: # no ACFT linked line1_sections.append('sq=%04o' % assSQ) else: sq = acft.xpdrCode() if sq != None and sq != assSQ: line1_sections.append('sq=%04o (%04o)' % (assSQ, sq)) # conflicts conflicts = [] alert_lvl_hi = alert_lvl_lo = False if strip.transponderConflictList() != []: conflicts.append('!!XPDR') alert_lvl_hi = True if sdl != None and sdl.status() != ConnectionStatus.OK: conflicts.append('!!CPDLC') if sdl.status() == ConnectionStatus.PROBLEM: alert_lvl_hi = True else: alert_lvl_lo = True if settings.strip_route_vect_warnings: if len(strip.vectoringConflicts(env.QNH())) != 0: conflicts.append('!!vect') alert_lvl_lo = True elif strip.routeConflict(): conflicts.append('!!route') alert_lvl_lo = True if len(conflicts) > 0: line1_sections.append(' '.join(conflicts)) ### LINE 2 line2_sections = [] if settings.APP_spacing_hints: prev = env.strips.previousInSequence(strip) if prev != None: hint = spacing_hint(strip, prev) if hint != None: line2_sections.append('%s ' % hint) parsed_route = strip.lookup(parsed_route_detail) if parsed_route == None: arr = strip.lookup(FPL.ICAO_ARR, fpl=True) if arr != None: line2_sections.append(arr) elif acft == None: line2_sections.append(str(parsed_route)) else: line2_sections.append(parsed_route.toGoStr(acft.coords())) ## MAKE DOCUMENT html_line1 = ' '.join(line1_sections) html_line2 = ' '.join(line2_sections) doc = QTextDocument(parent_widget) doc.setHtml('<html><body><p>%s<br> %s</p></body></html>' % (html_line1, html_line2)) ## PAINT painter.save() ## Background and borders if acft == None: if strip.lookup(soft_link_detail) == None: bgcol = 'strip_unlinked' else: bgcol = 'strip_unlinked_identified' else: # an aircraft is linked if alert_lvl_hi: bgcol = 'strip_linked_alert' elif alert_lvl_lo: bgcol = 'strip_linked_warning' else: bgcol = 'strip_linked_OK' if strip is selection.strip: painter.setPen(new_pen(Qt.black, width=2)) else: painter.setPen(new_pen(Qt.darkGray)) painter.setBrush(QBrush(settings.colour(bgcol))) painter.drawRect(rect) painter.translate(rect.topLeft()) rules = strip.lookup(FPL.FLIGHT_RULES, fpl=True) if rules != None: # add a border along bottom edge of strip painter.setPen(Qt.NoPen) painter.setBrush( QBrush(Qt.black, style={ 'IFR': Qt.SolidPattern, 'VFR': Qt.BDiagPattern }.get(rules, Qt.NoBrush))) painter.drawRect(0, rect.height() - strip_IFR_border_width, rect.width(), strip_IFR_border_width) ## Text contents doc.drawContents( painter, QRectF(0, 0, rect.width(), rect.height() - strip_IFR_border_width)) painter.restore()
class TextViewer(QWidget): def __init__(self, page, *args, **kwargs): self.page = page super(TextViewer, self).__init__(*args, **kwargs) self._document = QTextDocument(self) self._document.setUseDesignMetrics(True) self._page_number = 0 self.__offset_top = 0 def document(self): return self._document def setHtml(self, html): self._html = html self._updateHtml() def _offset_top(self): # FIXME the top offset is only on the first page, but this is ugly if self._page_number == 0: self.__offset_top = self.page.height() - self.height() return self.__offset_top def _updateHtml(self): css = textwrap.dedent(""" <style type="text/css"> tr.header {background: #BBB} tr.even {background: #CCC} tr.odd {background: #FFF} div.markdown {margin-top: %(margin)dpx} </style> """).strip() # make room for the "header" widgets css = css % {"margin": self._offset_top()} # print("css = %s" % css) html = '%s\n<div class="markdown">%s<span>' % (css, self._html) # print("setHtml <- %s" % html) self._document.setDefaultFont(self.font()) self._document.setHtml(html) def resizeEvent(self, resize_event): size = self.page.size() #print("setPageSize <- %s" % size) #old_size = self._document.pageSize() new_size = QSizeF(size.width(), size.height()) self._document.setPageSize(new_size) #print("self.size = %s" % self.size()) self._updateHtml() def paintEvent(self, paint_event): painter = QPainter(self) if self._page_number == 0: painter.setClipRect(QRectF(0, 0, self.page.width(), self.page.height()-self._offset_top())) painter.translate(0, -self._offset_top()) else: painter.setClipRect(QRectF(0, 0, self.page.width(), self.page.height())) height = self.page.height() painter.translate(0, -self._page_number*height) self._document.drawContents(painter) def pageCount(self): return self._document.pageCount() def setPageNumber(self, num): print("setPageNumber <- %s" % num) self._page_number = num self.update() def pageNumber(self): return self._page_number
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)
class LibraryDelegate(QStyledItemDelegate): """Delegate used for the library. The delegate draws the items. """ # Storing the styles makes the code more readable and faster IMHO # pylint: disable=too-many-instance-attributes def __init__(self): super().__init__() self.doc = QTextDocument(self) self.doc.setDocumentMargin(0) # Named properties for html self.font = styles.get("library.font") self.fg = styles.get("library.fg") self.dir_fg = styles.get("library.directory.fg") self.search_fg = styles.get("library.search.highlighted.fg") # QColor options for background drawing self.selection_bg = QColor(styles.get("library.selected.bg")) self.selection_bg_unfocus = QColor( styles.get("library.selected.bg.unfocus")) self.even_bg = QColor(styles.get("library.even.bg")) self.odd_bg = QColor(styles.get("library.odd.bg")) self.search_bg = QColor(styles.get("library.search.highlighted.bg")) self.mark_str = api.mark.highlight("") def createEditor(self, *_): """Library is not editable by the user.""" return None def paint(self, painter, option, index): """Override the QStyledItemDelegate paint function. Args: painter: The QPainter. option: The QStyleOptionViewItem. index: The QModelIndex. """ self._draw_background(painter, option, index) self._draw_text(painter, option, index) def _draw_text(self, painter, option, index): """Draw text for the library. Sets the font and the foreground color using html. The foreground color depends on whether the path is a directory and on whether it is highlighted as search result or not. Args: painter: The QPainter. option: The QStyleOptionViewItem. index: The QModelIndex. """ text = index.model().data(index) painter.save() color = self._get_foreground_color(index, text) text = self.elided(text, painter.fontMetrics(), option.rect.width() - 1) text = wrap_style_span(f"color: {color}; font: {self.font}", text) self.doc.setHtml(text) self.doc.setTextWidth(option.rect.width() - 1) painter.translate(option.rect.x(), option.rect.y()) self.doc.drawContents(painter) painter.restore() def _draw_background(self, painter, option, index): """Draw the background rectangle of the text. The color depends on whether the item is selected, in an even row or in an odd row. Args: painter: The QPainter. option: The QStyleOptionViewItem. index: The QModelIndex. """ color = self._get_background_color(index, option.state) painter.save() painter.setBrush(color) painter.setPen(Qt.NoPen) painter.drawRect(option.rect) painter.restore() def _get_foreground_color(self, index, text): """Return the foreground color of an item. The color depends on highlighted as search result and whether it is a directory. Args: index: Index of the element indicating even/odd/highlighted. text: Text indicating directory or not. """ if index.model().is_highlighted(index): return self.search_fg return self.dir_fg if text.endswith("/") else self.fg def _get_background_color(self, index, state): """Return the background color of an item. The color depends on selected, highlighted as search result and even/odd. Args: index: Index of the element indicating even/odd/highlighted. state: State of the index indicating selected. """ if state & QStyle.State_Selected: if api.modes.current() == api.modes.LIBRARY: return self.selection_bg return self.selection_bg_unfocus if index.model().is_highlighted(index): return self.search_bg if index.row() % 2: return self.odd_bg return self.even_bg def elided(self, text, font_metrics, width): """Return an elided text preserving html tags. If the text is wider than width, it is elided by replacing characters from the middle by …. Surrounding html tags are not included in the calculation and left untouched. Args: text: The text to elide. font_metrics: QFontMetrics to create elided text based on width. width: Width in pixels that the text may take. Returns: Elided version of the text. """ html_stripped = strip_html(text) # Html only surrounds the leading mark indicator as directories are never marked if text.startswith(self.mark_str): mark_stripped = strip_html(self.mark_str) elided = font_metrics.elidedText(html_stripped, Qt.ElideMiddle, width) return elided.replace(mark_stripped, self.mark_str) # Html surrounds the full text as the file may be a directory which is displayed # in bold elided = font_metrics.elidedText(html_stripped, Qt.ElideMiddle, width) return text.replace(html_stripped, elided)
def paint(self, painter, option, index): assert isinstance(painter, QPainter) if index.data(Qt.UserRole+1): if app_constants.HIGH_QUALITY_THUMBS: painter.setRenderHint(QPainter.SmoothPixmapTransform) painter.setRenderHint(QPainter.Antialiasing) gallery = index.data(Qt.UserRole+1) title = gallery.title artist = gallery.artist title_color = app_constants.GRID_VIEW_TITLE_COLOR artist_color = app_constants.GRID_VIEW_ARTIST_COLOR label_color = app_constants.GRID_VIEW_LABEL_COLOR # Enable this to see the defining box #painter.drawRect(option.rect) # define font size if 20 > len(title) > 15: title_size = "font-size:{}px;".format(self.font_size) elif 30 > len(title) > 20: title_size = "font-size:{}px;".format(self.font_size-1) elif 40 > len(title) >= 30: title_size = "font-size:{}px;".format(self.font_size-2) elif 50 > len(title) >= 40: title_size = "font-size:{}px;".format(self.font_size-3) elif len(title) >= 50: title_size = "font-size:{}px;".format(self.font_size-4) else: title_size = "font-size:{}px;".format(self.font_size) if 30 > len(artist) > 20: artist_size = "font-size:{}px;".format(self.font_size) elif 40 > len(artist) >= 30: artist_size = "font-size:{}px;".format(self.font_size-1) elif len(artist) >= 40: artist_size = "font-size:{}px;".format(self.font_size-2) else: artist_size = "font-size:{}px;".format(self.font_size) #painter.setPen(QPen(Qt.NoPen)) #option.rect = option.rect.adjusted(11, 10, 0, 0) option.rect.setWidth(self.W) option.rect.setHeight(self.H) rec = option.rect.getRect() x = rec[0] y = rec[1] w = rec[2] h = rec[3] text_area = QTextDocument() text_area.setDefaultFont(option.font) text_area.setHtml(""" <head> <style> #area {{ display:flex; width:{6}px; height:{7}px }} #title {{ position:absolute; color: {4}; font-weight:bold; {0} }} #artist {{ position:absolute; color: {5}; top:20px; right:0; {1} }} </style> </head> <body> <div id="area"> <center> <div id="title">{2} </div> <div id="artist">{3} </div> </div> </center> </body> """.format(title_size, artist_size, title, artist, title_color, artist_color, 130+app_constants.SIZE_FACTOR, 1+app_constants.SIZE_FACTOR)) text_area.setTextWidth(w) #chapter_area = QTextDocument() #chapter_area.setDefaultFont(option.font) #chapter_area.setHtml(""" #<font color="black">{}</font> #""".format("chapter")) #chapter_area.setTextWidth(w) def center_img(width): new_x = x if width < w: diff = w - width offset = diff//2 new_x += offset return new_x def img_too_big(start_x): txt_layout = misc.text_layout("Image is too big!", w, self.title_font, self.title_font_m) clipping = QRectF(x, y+h//4, w, app_constants.GRIDBOX_LBL_H - 10) txt_layout.draw(painter, QPointF(x, y+h//4), clip=clipping) # if we can't find a cached image pix_cache = QPixmapCache.find(self.key(gallery.profile)) if isinstance(pix_cache, QPixmap): self.image = pix_cache img_x = center_img(self.image.width()) if self.image.width() > w or self.image.height() > h: img_too_big(img_x) else: if self.image.height() < self.image.width(): #to keep aspect ratio painter.drawPixmap(QPoint(img_x,y), self.image) else: painter.drawPixmap(QPoint(img_x,y), self.image) else: self.image = QPixmap(gallery.profile) img_x = center_img(self.image.width()) QPixmapCache.insert(self.key(gallery.profile), self.image) if self.image.width() > w or self.image.height() > h: img_too_big(img_x) else: if self.image.height() < self.image.width(): #to keep aspect ratio painter.drawPixmap(QPoint(img_x,y), self.image) else: painter.drawPixmap(QPoint(img_x,y), self.image) # draw ribbon type painter.save() painter.setPen(Qt.NoPen) if app_constants.DISPLAY_GALLERY_RIBBON: type_ribbon_w = type_ribbon_l = w*0.11 rib_top_1 = QPointF(x+w-type_ribbon_l-type_ribbon_w, y) rib_top_2 = QPointF(x+w-type_ribbon_l, y) rib_side_1 = QPointF(x+w, y+type_ribbon_l) rib_side_2 = QPointF(x+w, y+type_ribbon_l+type_ribbon_w) ribbon_polygon = QPolygonF([rib_top_1, rib_top_2, rib_side_1, rib_side_2]) ribbon_path = QPainterPath() ribbon_path.setFillRule(Qt.WindingFill) ribbon_path.addPolygon(ribbon_polygon) ribbon_path.closeSubpath() painter.setBrush(QBrush(QColor(self._ribbon_color(gallery.type)))) painter.drawPath(ribbon_path) # draw if favourited if gallery.fav == 1: star_ribbon_w = star_ribbon_l = w*0.08 rib_top_1 = QPointF(x+star_ribbon_l, y) rib_side_1 = QPointF(x, y+star_ribbon_l) rib_top_2 = QPointF(x+star_ribbon_l+star_ribbon_w, y) rib_side_2 = QPointF(x, y+star_ribbon_l+star_ribbon_w) rib_star_mid_1 = QPointF((rib_top_1.x()+rib_side_1.x())/2, (rib_top_1.y()+rib_side_1.y())/2) rib_star_factor = star_ribbon_l/4 rib_star_p1_1 = rib_star_mid_1 + QPointF(rib_star_factor, -rib_star_factor) rib_star_p1_2 = rib_star_p1_1 + QPointF(-rib_star_factor, -rib_star_factor) rib_star_p1_3 = rib_star_mid_1 + QPointF(-rib_star_factor, rib_star_factor) rib_star_p1_4 = rib_star_p1_3 + QPointF(-rib_star_factor, -rib_star_factor) crown_1 = QPolygonF([rib_star_p1_1, rib_star_p1_2, rib_star_mid_1, rib_star_p1_4, rib_star_p1_3]) painter.setBrush(QBrush(QColor("yellow"))) painter.drawPolygon(crown_1) ribbon_polygon = QPolygonF([rib_top_1, rib_side_1, rib_side_2, rib_top_2]) ribbon_path = QPainterPath() ribbon_path.setFillRule(Qt.WindingFill) ribbon_path.addPolygon(ribbon_polygon) ribbon_path.closeSubpath() painter.drawPath(ribbon_path) #painter.setPen(QColor("#d35400")) #painter.drawPolyline(rib_top_1, rib_star_p1_1, rib_star_p1_2, rib_star_mid_1, rib_star_p1_4, rib_star_p1_3, rib_side_1) #painter.drawLine(rib_top_1, rib_top_2) #painter.drawLine(rib_top_2, rib_side_2) #painter.drawLine(rib_side_1, rib_side_2) painter.restore() if app_constants._REFRESH_EXTERNAL_VIEWER: if app_constants.USE_EXTERNAL_VIEWER: self.external_icon = self.file_icons.get_external_file_icon() else: self.external_icon = self.file_icons.get_default_file_icon() if gallery.state == self.G_DOWNLOAD: painter.save() dl_box = QRect(x, y, w, 20) painter.setBrush(QBrush(QColor(0,0,0,123))) painter.setPen(QColor('white')) painter.drawRect(dl_box) painter.drawText(dl_box, Qt.AlignCenter, 'Downloading...') painter.restore() else: if app_constants.DISPLAY_GALLERY_TYPE: self.type_icon = self.file_icons.get_file_icon(gallery.path) if self.type_icon and not self.type_icon.isNull(): self.type_icon.paint(painter, QRect(x+2, y+app_constants.THUMB_H_SIZE-16, 16, 16)) if app_constants.USE_EXTERNAL_PROG_ICO: if self.external_icon and not self.external_icon.isNull(): self.external_icon.paint(painter, QRect(x+w-30, y+app_constants.THUMB_H_SIZE-28, 28, 28)) def draw_text_label(lbl_h): #draw the label for text painter.save() painter.translate(x, y+app_constants.THUMB_H_SIZE) box_color = QBrush(QColor(label_color))#QColor(0,0,0,123)) painter.setBrush(box_color) rect = QRect(0, 0, w, lbl_h) #x, y, width, height painter.fillRect(rect, box_color) painter.restore() return rect if option.state & QStyle.State_MouseOver or\ option.state & QStyle.State_Selected: title_layout = misc.text_layout(title, w, self.title_font, self.title_font_m) artist_layout = misc.text_layout(artist, w, self.artist_font, self.artist_font_m) t_h = title_layout.boundingRect().height() a_h = artist_layout.boundingRect().height() if app_constants.GALLERY_FONT_ELIDE: lbl_rect = draw_text_label(min(t_h+a_h+3, app_constants.GRIDBOX_LBL_H)) else: lbl_rect = draw_text_label(app_constants.GRIDBOX_LBL_H) clipping = QRectF(x, y+app_constants.THUMB_H_SIZE, w, app_constants.GRIDBOX_LBL_H - 10) painter.setPen(QColor(title_color)) title_layout.draw(painter, QPointF(x, y+app_constants.THUMB_H_SIZE), clip=clipping) painter.setPen(QColor(artist_color)) artist_layout.draw(painter, QPointF(x, y+app_constants.THUMB_H_SIZE+t_h), clip=clipping) #painter.fillRect(option.rect, QColor) else: if app_constants.GALLERY_FONT_ELIDE: lbl_rect = draw_text_label(self.text_label_h) else: lbl_rect = draw_text_label(app_constants.GRIDBOX_LBL_H) # draw text painter.save() alignment = QTextOption(Qt.AlignCenter) alignment.setUseDesignMetrics(True) title_rect = QRectF(0,0,w, self.title_font_m.height()) artist_rect = QRectF(0,self.artist_font_m.height(),w, self.artist_font_m.height()) painter.translate(x, y+app_constants.THUMB_H_SIZE) if app_constants.GALLERY_FONT_ELIDE: painter.setFont(self.title_font) painter.setPen(QColor(title_color)) painter.drawText(title_rect, self.title_font_m.elidedText(title, Qt.ElideRight, w-10), alignment) painter.setPen(QColor(artist_color)) painter.setFont(self.artist_font) alignment.setWrapMode(QTextOption.NoWrap) painter.drawText(artist_rect, self.title_font_m.elidedText(artist, Qt.ElideRight, w-10), alignment) else: text_area.setDefaultFont(QFont(self.font_name)) text_area.drawContents(painter) ##painter.resetTransform() painter.restore() if option.state & QStyle.State_Selected: painter.save() selected_rect = QRectF(x, y, w, lbl_rect.height()+app_constants.THUMB_H_SIZE) painter.setPen(Qt.NoPen) painter.setBrush(QBrush(QColor(164,164,164,120))) painter.drawRoundedRect(selected_rect, 5, 5) #painter.fillRect(selected_rect, QColor(164,164,164,120)) painter.restore() if gallery.dead_link: painter.save() selected_rect = QRectF(x, y, w, lbl_rect.height()+app_constants.THUMB_H_SIZE) painter.setPen(Qt.NoPen) painter.setBrush(QBrush(QColor(255,0,0,120))) p_path = QPainterPath() p_path.setFillRule(Qt.WindingFill) p_path.addRoundedRect(selected_rect, 5,5) p_path.addRect(x,y, 20, 20) p_path.addRect(x+w-20,y, 20, 20) painter.drawPath(p_path.simplified()) painter.setPen(QColor("white")) txt_layout = misc.text_layout("Cannot find gallery source!", w, self.title_font, self.title_font_m) txt_layout.draw(painter, QPointF(x, y+h*0.3)) painter.restore() if app_constants.DEBUG: painter.save() painter.setBrush(QBrush(QColor("red"))) painter.setPen(QColor("white")) txt_l = self.title_font_m.width(str(gallery.id)) painter.drawRect(x, y+40, txt_l*2, self.title_font_m.height()) painter.drawText(x+1, y+51, str(gallery.id)) painter.restore() if option.state & QStyle.State_Selected: painter.setPen(QPen(option.palette.highlightedText().color())) else: super().paint(painter, option, index)
class TAText2D(Rect2D): def __init__(self, text=None, doc=None, opacity=1., *args, **kwargs): if doc is not None and isinstance(doc, QTextDocument): self.doc = doc self.doc.setDocumentMargin( 0) # important so that the square is properly placed else: self.doc = QTextDocument() self.doc.setDocumentMargin( 0) # important so that the square is properly placed textOption = self.doc.defaultTextOption() textOption.setWrapMode(QTextOption.NoWrap) self.doc.setDefaultTextOption(textOption) if text is not None: self.doc.setHtml(text) self.isSet = True self.doc.adjustSize() size = self.getSize() super(TAText2D, self).__init__(0, 0, size.width(), size.height()) self.opacity = opacity def setText(self, html): self.doc.setHtml(html) self.doc.adjustSize() size = self.getSize() self.setWidth(size.width(), size.height()) def setDoc(self, doc): self.doc = doc self.doc.setDocumentMargin(0) self.doc.adjustSize() size = self.getSize() self.setWidth(size.width(), size.height()) def draw(self, painter): painter.save() painter.setOpacity(self.opacity) painter.translate(self.x(), self.y()) self.doc.drawContents(painter) painter.restore() painter.save() painter.setPen(QtCore.Qt.red) painter.drawRect(self) painter.restore() def boundingRect(self): return self def getSize(self): return self.doc.size() def getWidth(self): return self.boundingRect().width() def getHeight(self): return self.boundingRect().height() def setText(self, text): self.doc.setHtml(text) size = self.size() self.setWidth(size.width(), size.height()) def set_P1(self, *args): if not args: logger.error("no coordinate set...") return if len(args) == 1: self.moveTo(args[0].x(), args[0].y()) else: self.moveTo(QPointF(args[0], args[1])) def get_P1(self): return QPointF(self.x(), self.y()) def getPlainText(self): return self.doc.toPlainText() def getHtmlText(self): return self.doc.toHtml()
def paint(self, painter, option, index): msg = index.model().data(index, Qt.DisplayRole) field = QRect(option.rect) field = field.marginsRemoved(variables.TEXT_PADDING) doc = QTextDocument(msg.text) doc.setDocumentMargin(0) opt = QTextOption() opt.setWrapMode(opt.WrapAtWordBoundaryOrAnywhere) doc.setDefaultTextOption(opt) doc.setDefaultFont(variables.font) if msg.user == variables.USER_ME: doc.setTextWidth(field.size().width() - 20 - 50) else: doc.setTextWidth(field.size().width() - 20) field.setHeight(int(doc.size().height())) field.setWidth(int(doc.idealWidth())) field = field.marginsAdded(variables.TEXT_PADDING) line_height = QFontMetrics(variables.font).lineSpacing( ) + variables.TEXT_PADDING.bottom() - variables.BUBBLE_PADDING.bottom( ) + variables.TEXT_PADDING.top() - variables.BUBBLE_PADDING.top() if msg.user == variables.USER_ME: rect = QRect(option.rect.right() - field.size().width() - 20, option.rect.top(), field.size().width(), field.size().height()) else: rect = QRect(20, option.rect.top(), field.size().width(), field.size().height()) bubblerect = rect.marginsRemoved(variables.BUBBLE_PADDING) textrect = rect.marginsRemoved(variables.TEXT_PADDING) if msg.user == variables.USER_ME: p1 = bubblerect.topRight() p2 = bubblerect.bottomLeft() + QPoint(-36, -int(line_height / 2)) else: p1 = bubblerect.topLeft() painter.setRenderHint(QPainter.Antialiasing) painter.setPen(Qt.NoPen) color = QColor(variables.BUBBLE_COLORS[msg.user]) painter.setBrush(color) painter.drawRoundedRect(bubblerect, 10, 10) painter.drawPolygon(p1 + QPoint(-20, 0), p1 + QPoint(20, 0), p1 + QPoint(0, 15)) if msg.user == variables.USER_ME: if msg.status == variables.STATUS_UNREAD: painter.setPen(Qt.NoPen) painter.setBrush(QColor(variables.STATUS_COLOR)) painter.drawEllipse(p2, 7, 7) elif msg.status == variables.STATUS_UNDELIVERED: pen = QPen(QColor(variables.STATUS_COLOR)) pen.setWidth(2) painter.setPen(pen) painter.setBrush(Qt.NoBrush) painter.drawEllipse(p2, 7, 7) painter.drawLine(p2, p2 + QPoint(0, -5)) painter.drawLine(p2, p2 + QPoint(3, 0)) painter.setPen(Qt.gray) 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())
def paint(self, painter, option, index): assert isinstance(painter, QPainter) if index.data(Qt.UserRole+1): if app_constants.HIGH_QUALITY_THUMBS: painter.setRenderHint(QPainter.SmoothPixmapTransform) painter.setRenderHint(QPainter.Antialiasing) gallery = index.data(Qt.UserRole+1) title = gallery.title artist = gallery.artist title_color = app_constants.GRID_VIEW_TITLE_COLOR artist_color = app_constants.GRID_VIEW_ARTIST_COLOR label_color = app_constants.GRID_VIEW_LABEL_COLOR # Enable this to see the defining box #painter.drawRect(option.rect) # define font size if 20 > len(title) > 15: title_size = "font-size:{}px;".format(self.font_size) elif 30 > len(title) > 20: title_size = "font-size:{}px;".format(self.font_size-1) elif 40 > len(title) >= 30: title_size = "font-size:{}px;".format(self.font_size-2) elif 50 > len(title) >= 40: title_size = "font-size:{}px;".format(self.font_size-3) elif len(title) >= 50: title_size = "font-size:{}px;".format(self.font_size-4) else: title_size = "font-size:{}px;".format(self.font_size) if 30 > len(artist) > 20: artist_size = "font-size:{}px;".format(self.font_size) elif 40 > len(artist) >= 30: artist_size = "font-size:{}px;".format(self.font_size-1) elif len(artist) >= 40: artist_size = "font-size:{}px;".format(self.font_size-2) else: artist_size = "font-size:{}px;".format(self.font_size) #painter.setPen(QPen(Qt.NoPen)) #option.rect = option.rect.adjusted(11, 10, 0, 0) option.rect.setWidth(self.W) option.rect.setHeight(self.H) rec = option.rect.getRect() x = rec[0] y = rec[1] w = rec[2] h = rec[3] text_area = QTextDocument() text_area.setDefaultFont(option.font) text_area.setHtml(""" <head> <style> #area {{ display:flex; width:140px; height:10px }} #title {{ position:absolute; color: {4}; font-weight:bold; {0} }} #artist {{ position:absolute; color: {5}; top:20px; right:0; {1} }} </style> </head> <body> <div id="area"> <center> <div id="title">{2} </div> <div id="artist">{3} </div> </div> </center> </body> """.format(title_size, artist_size, title, artist, title_color, artist_color)) text_area.setTextWidth(w) #chapter_area = QTextDocument() #chapter_area.setDefaultFont(option.font) #chapter_area.setHtml(""" #<font color="black">{}</font> #""".format("chapter")) #chapter_area.setTextWidth(w) def center_img(width): new_x = x if width < w: diff = w - width offset = diff//2 new_x += offset return new_x # if we can't find a cached image pix_cache = QPixmapCache.find(self.key(gallery.profile)) if isinstance(pix_cache, QPixmap): self.image = pix_cache img_x = center_img(self.image.width()) if self.image.height() < self.image.width(): #to keep aspect ratio painter.drawPixmap(QPoint(img_x,y), self.image) else: painter.drawPixmap(QPoint(img_x,y), self.image) else: self.image = QPixmap(gallery.profile) img_x = center_img(self.image.width()) QPixmapCache.insert(self.key(gallery.profile), self.image) if self.image.height() < self.image.width(): #to keep aspect ratio painter.drawPixmap(QPoint(img_x,y), self.image) else: painter.drawPixmap(QPoint(img_x,y), self.image) # draw star if it's favorited if gallery.fav == 1: painter.drawPixmap(QPointF(x,y), QPixmap(app_constants.STAR_PATH)) if app_constants._REFRESH_EXTERNAL_VIEWER: if app_constants.USE_EXTERNAL_VIEWER: self.external_icon = self.file_icons.get_external_file_icon() else: self.external_icon = self.file_icons.get_default_file_icon() if gallery.state == self.G_DOWNLOAD: painter.save() dl_box = QRect(x, y, w, 20) painter.setBrush(QBrush(QColor(0,0,0,123))) painter.setPen(QColor('white')) painter.drawRect(dl_box) painter.drawText(dl_box, Qt.AlignCenter, 'Downloading...') painter.restore() else: if app_constants.DISPLAY_GALLERY_TYPE: self.type_icon = self.file_icons.get_file_icon(gallery.path) if self.type_icon and not self.type_icon.isNull(): self.type_icon.paint(painter, QRect(x+2, y+app_constants.THUMB_H_SIZE-16, 16, 16)) if app_constants.USE_EXTERNAL_PROG_ICO: if self.external_icon and not self.external_icon.isNull(): self.external_icon.paint(painter, QRect(x+w-30, y+app_constants.THUMB_H_SIZE-28, 28, 28)) def draw_text_label(lbl_h): #draw the label for text painter.save() painter.translate(x, y+app_constants.THUMB_H_SIZE) box_color = QBrush(QColor(label_color))#QColor(0,0,0,123)) painter.setBrush(box_color) rect = QRect(0, 0, w, lbl_h) #x, y, width, height painter.fillRect(rect, box_color) painter.restore() return rect if option.state & QStyle.State_MouseOver or\ option.state & QStyle.State_Selected: title_layout = self.text_layout(title, w, self.title_font, self.title_font_m) artist_layout = self.text_layout(artist, w, self.artist_font, self.artist_font_m) t_h = title_layout.boundingRect().height() a_h = artist_layout.boundingRect().height() if app_constants.GALLERY_FONT_ELIDE: lbl_rect = draw_text_label(min(t_h+a_h+3, app_constants.GRIDBOX_LBL_H)) else: lbl_rect = draw_text_label(app_constants.GRIDBOX_LBL_H) clipping = QRectF(x, y+app_constants.THUMB_H_SIZE, w, app_constants.GRIDBOX_LBL_H - 10) title_layout.draw(painter, QPointF(x, y+app_constants.THUMB_H_SIZE), clip=clipping) artist_layout.draw(painter, QPointF(x, y+app_constants.THUMB_H_SIZE+t_h), clip=clipping) #painter.fillRect(option.rect, QColor) else: if app_constants.GALLERY_FONT_ELIDE: lbl_rect = draw_text_label(self.text_label_h) else: lbl_rect = draw_text_label(app_constants.GRIDBOX_LBL_H) # draw text painter.save() alignment = QTextOption(Qt.AlignCenter) alignment.setUseDesignMetrics(True) title_rect = QRectF(0,0,w, self.title_font_m.height()) artist_rect = QRectF(0,self.artist_font_m.height(),w, self.artist_font_m.height()) painter.translate(x, y+app_constants.THUMB_H_SIZE) if app_constants.GALLERY_FONT_ELIDE: painter.setFont(self.title_font) painter.setPen(QColor(title_color)) painter.drawText(title_rect, self.title_font_m.elidedText(title, Qt.ElideRight, w-10), alignment) painter.setPen(QColor(artist_color)) painter.setFont(self.artist_font) alignment.setWrapMode(QTextOption.NoWrap) painter.drawText(artist_rect, self.title_font_m.elidedText(artist, Qt.ElideRight, w-10), alignment) else: text_area.setDefaultFont(QFont(self.font_name)) text_area.drawContents(painter) ##painter.resetTransform() painter.restore() if option.state & QStyle.State_Selected: painter.save() selected_rect = QRectF(x, y, w, lbl_rect.height()+app_constants.THUMB_H_SIZE) painter.setPen(Qt.NoPen) painter.setBrush(QBrush(QColor(164,164,164,120))) p_path = QPainterPath() p_path.setFillRule(Qt.WindingFill) p_path.addRoundedRect(selected_rect, 5,5) p_path.addRect(x,y, 20, 20) p_path.addRect(x+w-20,y, 20, 20) painter.drawPath(p_path.simplified()) #painter.fillRect(selected_rect, QColor(164,164,164,120)) painter.restore() #if option.state & QStyle.State_Selected: # painter.setPen(QPen(option.palette.highlightedText().color())) else: super().paint(painter, option, index)