def paint(self, painter, option, index): QStyledItemDelegate.paint(self, painter, option, index) pal = option.palette color = pal.color(QPalette.ColorRole.HighlightedText if option.state & QStyle.StateFlag.State_Selected else QPalette.ColorRole.Text).name() text = '<div style="color:%s">%s</div>' % (color, index.data(RENDER_ROLE)) st = QStaticText(text) st.setTextWidth(option.rect.width()) painter.drawStaticText(option.rect.left() + self.MARGIN // 2, option.rect.top() + self.MARGIN // 2, st)
def __init__(self, parent=None): QWidget.__init__(self, parent=parent) self.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding) self.results = () self.current_result = -1 self.max_result = -1 self.mouse_hover_result = -1 self.setMouseTracking(True) self.setFocusPolicy(Qt.FocusPolicy.NoFocus) self.text_option = to = QTextOption() to.setWrapMode(QTextOption.WrapMode.NoWrap) self.divider = QStaticText('\xa0→ \xa0') self.divider.setTextFormat(Qt.TextFormat.PlainText)
def sizeHint(self, option, index): st = QStaticText(index.data(RENDER_ROLE)) st.prepare(font=self.parent().font()) width = max(option.rect.width(), self.parent().width() - 50) if width and width != st.textWidth(): st.setTextWidth(width) br = st.size() return QSize(br.width() + self.MARGIN, br.height() + self.MARGIN)
def __call__(self, results): if results: self.current_result = 0 prefixes = [QStaticText('<b>%s</b>' % os.path.basename(x)) for x in results] [(p.setTextFormat(Qt.TextFormat.RichText), p.setTextOption(self.text_option)) for p in prefixes] self.maxwidth = max(int(ceil(x.size().width())) for x in prefixes) self.results = tuple((prefix, self.make_text(text, positions), text) for prefix, (text, positions) in zip(prefixes, iteritems(results))) else: self.results = () self.current_result = -1 self.max_result = min(10, len(self.results) - 1) self.mouse_hover_result = -1 self.update()
def get_static_text(self, otext, positions): st = self.rendered_text_cache.get(otext) if st is None: text = (otext or '').ljust(self.max_text_length + 1, '\xa0') text = make_highlighted_text('color: magenta', text, positions) desc = self.descriptions.get(otext) if desc: text += ' - <i>%s</i>' % prepare_string_for_xml(desc) color = self.palette().color(QPalette.ColorRole.Text).name() text = '<span style="color: %s">%s</span>' % (color, text) st = self.rendered_text_cache[otext] = QStaticText(text) st.setTextOption(self.text_option) st.setTextFormat(Qt.TextFormat.RichText) st.prepare(font=self.parent().font()) return st
def paintEvent(self, ev): painter = QPainter(self) painter.setClipRect(ev.rect()) pal = self.palette() painter.fillRect(self.rect(), pal.color(QPalette.ColorRole.Text)) crect = self.rect().adjusted(1, 1, -1, -1) painter.fillRect(crect, pal.color(QPalette.ColorRole.Base)) painter.setClipRect(crect) painter.setFont(self.parent().font()) width = self.rect().width() for i, st, y, height in self.iter_visible_items(): painter.save() if i == self.current_index: painter.fillRect(1, y, width, height, pal.color(QPalette.ColorRole.Highlight)) color = pal.color(QPalette.ColorRole.HighlightedText).name() st = QStaticText(st) text = st.text().partition('>')[2] st.setText('<span style="color: %s">%s' % (color, text)) painter.drawStaticText(self.SIDE_MARGIN, y, st) painter.restore() painter.end() if self.current_size_hint is None: QTimer.singleShot(0, self.layout)
def paint(self, painter, option, index): QStyledItemDelegate.paint(self, painter, option, empty_index) theme = index.data(Qt.ItemDataRole.UserRole) if not theme: return painter.save() pixmap = index.data(Qt.ItemDataRole.DecorationRole) if pixmap and not pixmap.isNull(): rect = option.rect.adjusted(0, self.SPACING, COVER_SIZE[0] - option.rect.width(), -self.SPACING) painter.drawPixmap(rect, pixmap) if option.state & QStyle.StateFlag.State_Selected: painter.setPen( QPen(QApplication.instance().palette().highlightedText().color( ))) bottom = option.rect.bottom() - 2 painter.drawLine(0, bottom, option.rect.right(), bottom) if 'static-text' not in theme: theme['static-text'] = QStaticText( _(''' <h1>{title}</h1> <p>by <i>{author}</i> with <b>{number}</b> icons [{size}]</p> <p>{description}</p> <p>Version: {version} Number of users: {usage}</p> <p><i>Right click to visit theme homepage</i></p> '''.format( title=theme.get('title', _('Unknown')), author=theme.get('author', _('Unknown')), number=theme.get('number', 0), description=theme.get('description', ''), size=human_readable(theme.get('compressed-size', 0)), version=theme.get('version', 1), usage=theme.get('usage', 0), ))) painter.drawStaticText(COVER_SIZE[0] + self.SPACING, option.rect.top() + self.SPACING, theme['static-text']) painter.restore()
def make_text(self, text, positions): text = QStaticText(make_highlighted_text(emphasis_style(), text, positions)) text.setTextOption(self.text_option) text.setTextFormat(Qt.TextFormat.RichText) return text
class Results(QWidget): MARGIN = 4 item_selected = pyqtSignal() def __init__(self, parent=None): QWidget.__init__(self, parent=parent) self.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding) self.results = () self.current_result = -1 self.max_result = -1 self.mouse_hover_result = -1 self.setMouseTracking(True) self.setFocusPolicy(Qt.FocusPolicy.NoFocus) self.text_option = to = QTextOption() to.setWrapMode(QTextOption.WrapMode.NoWrap) self.divider = QStaticText('\xa0→ \xa0') self.divider.setTextFormat(Qt.TextFormat.PlainText) def item_from_y(self, y): if not self.results: return delta = self.results[0][0].size().height() + self.MARGIN maxy = self.height() pos = 0 for i, r in enumerate(self.results): bottom = pos + delta if pos <= y < bottom: return i break pos = bottom if pos > min(y, maxy): break return -1 def mouseMoveEvent(self, ev): y = ev.pos().y() prev = self.mouse_hover_result self.mouse_hover_result = self.item_from_y(y) if prev != self.mouse_hover_result: self.update() def mousePressEvent(self, ev): if ev.button() == 1: i = self.item_from_y(ev.pos().y()) if i != -1: ev.accept() self.current_result = i self.update() self.item_selected.emit() return return QWidget.mousePressEvent(self, ev) def change_current(self, delta=1): if not self.results: return nc = self.current_result + delta if 0 <= nc <= self.max_result: self.current_result = nc self.update() def __call__(self, results): if results: self.current_result = 0 prefixes = [QStaticText('<b>%s</b>' % os.path.basename(x)) for x in results] [(p.setTextFormat(Qt.TextFormat.RichText), p.setTextOption(self.text_option)) for p in prefixes] self.maxwidth = max(int(ceil(x.size().width())) for x in prefixes) self.results = tuple((prefix, self.make_text(text, positions), text) for prefix, (text, positions) in zip(prefixes, iteritems(results))) else: self.results = () self.current_result = -1 self.max_result = min(10, len(self.results) - 1) self.mouse_hover_result = -1 self.update() def make_text(self, text, positions): text = QStaticText(make_highlighted_text(emphasis_style(), text, positions)) text.setTextOption(self.text_option) text.setTextFormat(Qt.TextFormat.RichText) return text def paintEvent(self, ev): offset = QPoint(0, 0) p = QPainter(self) p.setClipRect(ev.rect()) bottom = self.rect().bottom() if self.results: for i, (prefix, full, text) in enumerate(self.results): size = prefix.size() if offset.y() + size.height() > bottom: break self.max_result = i offset.setX(0) if i in (self.current_result, self.mouse_hover_result): p.save() if i != self.current_result: p.setPen(Qt.PenStyle.DotLine) p.drawLine(offset, QPoint(self.width(), offset.y())) p.restore() offset.setY(offset.y() + self.MARGIN // 2) p.drawStaticText(offset, prefix) offset.setX(self.maxwidth + 5) p.drawStaticText(offset, self.divider) offset.setX(offset.x() + int(ceil(self.divider.size().width()))) p.drawStaticText(offset, full) offset.setY(int(offset.y() + size.height() + self.MARGIN // 2)) if i in (self.current_result, self.mouse_hover_result): offset.setX(0) p.save() if i != self.current_result: p.setPen(Qt.PenStyle.DotLine) p.drawLine(offset, QPoint(self.width(), offset.y())) p.restore() else: p.drawText(self.rect(), Qt.AlignmentFlag.AlignCenter, _('No results found')) p.end() @property def selected_result(self): try: return self.results[self.current_result][-1] except IndexError: pass