def paint(self, painter, option, index): painter.setRenderHints(QPainter.Antialiasing | QPainter.SmoothPixmapTransform) model = index.model() view = self.parent() if view.hasFocus() and option.state & QStyle.State_MouseOver: painter.setPen(Qt.NoPen) painter.setBrush(Qt.gray) painter.drawRoundedRect(option.rect.adjusted(1, 1, -1, -1), self._ICON_MARGIN, self._ICON_MARGIN) pixmap = model.data(index, Qt.DecorationRole).pixmap(view.iconSize()) pm_rect = QRect( option.rect.topLeft() + QPoint(self._ICON_MARGIN + 1, self._ICON_MARGIN + 1), view.iconSize() - QSize(self._ICON_MARGIN * 2, self._ICON_MARGIN * 2)) painter.drawPixmap(pm_rect, pixmap) if option.state & QStyle.State_Selected: painter.setPen( QPen(Qt.red, 1.0, Qt.SolidLine, Qt.SquareCap, Qt.RoundJoin)) painter.setBrush(Qt.NoBrush) painter.drawRect(option.rect.adjusted(2, 2, -2, -2)) font = view.font() fm = QFontMetrics(font) text = os.path.splitext( os.path.basename(model.data(index, Qt.DisplayRole)))[0] text = fm.elidedText(text, Qt.ElideRight, view.iconSize().width() - 4) text_opt = QTextOption() text_opt.setAlignment(Qt.AlignHCenter) txt_rect = QRectF(QPointF(pm_rect.bottomLeft() + QPoint(0, 1)), QPointF(option.rect.bottomRight() - QPoint(4, 3))) painter.save() painter.setPen(Qt.NoPen) painter.setBrush(QColor(22, 22, 22, 220)) painter.drawRoundedRect(txt_rect.adjusted(-2, -2, 2, 2), 2, 2) painter.restore() painter.setPen(self.parent().palette().color(QPalette.WindowText)) painter.drawText(txt_rect, text, text_opt) font.setPointSize(8) fm = QFontMetrics(font) item = model.itemFromIndex(index) size_text = '%d x %d' % (item.size.width(), item.size.height()) size_rect = fm.boundingRect(option.rect, Qt.AlignLeft | Qt.AlignTop, size_text) size_rect.translate(4, 4) painter.save() painter.setPen(Qt.NoPen) painter.setBrush(QColor(22, 22, 22, 220)) painter.drawRoundedRect(size_rect.adjusted(-2, -2, 2, 2), 2, 2) painter.restore() painter.setFont(font) painter.drawText(size_rect, size_text)
def create_drop_indicator_pixmap(palette, size, drop_area): border_color = palette.color(QPalette.Active, QPalette.Highlight) background_color = palette.color(QPalette.Active, QPalette.Base) area_background_color = palette.color(QPalette.Active, QPalette.Highlight).lighter(150) pm = QPixmap(size.width(), size.height()) pm.fill(QColor(0, 0, 0, 0)) painter = QPainter(pm) pen = painter.pen() base_rect = QRectF(pm.rect()) painter.fillRect(base_rect, background_color) painter.save() area_rect = QRectF() area_line = QLineF() gradient = QLinearGradient() if drop_area == DropArea.TopDropArea: area_rect = QRectF(base_rect.x(), base_rect.y(), base_rect.width(), base_rect.height() * 0.5) area_line = QLineF(area_rect.bottomLeft(), area_rect.bottomRight()) gradient.setStart(area_rect.topLeft()) gradient.setFinalStop(area_rect.bottomLeft()) gradient.setColorAt(0, area_background_color) gradient.setColorAt(1, area_background_color.lighter(120)) elif drop_area == DropArea.RightDropArea: area_rect = QRectF(base_rect.width() * 0.5, base_rect.y(), base_rect.width() * 0.5, base_rect.height()) area_line = QLineF(area_rect.topLeft(), area_rect.bottomLeft()) gradient.setStart(area_rect.topLeft()) gradient.setFinalStop(area_rect.topRight()) gradient.setColorAt(0, area_background_color.lighter(120)) gradient.setColorAt(1, area_background_color) elif drop_area == DropArea.BottomDropArea: area_rect = QRectF(base_rect.x(), base_rect.height() * 0.5, base_rect.width(), base_rect.height() * 0.5) area_line = QLineF(area_rect.topLeft(), area_rect.topRight()) gradient.setStart(area_rect.topLeft()) gradient.setFinalStop(area_rect.bottomLeft()) gradient.setColorAt(0, area_background_color.lighter(120)) gradient.setColorAt(1, area_background_color) elif drop_area == DropArea.LeftDropArea: area_rect = QRectF(base_rect.x(), base_rect.y(), base_rect.width() * 0.5, base_rect.height()) area_line = QLineF(area_rect.topRight(), area_rect.bottomRight()) gradient.setStart(area_rect.topLeft()) gradient.setFinalStop(area_rect.topRight()) gradient.setColorAt(0, area_background_color) gradient.setColorAt(1, area_background_color.lighter(120)) if area_rect.isValid(): painter.fillRect(area_rect, gradient) pen = painter.pen() pen.setColor(border_color) pen.setStyle(Qt.DashLine) painter.setPen(pen) painter.drawLine(area_line) painter.restore() painter.save() pen = painter.pen() pen.setColor(border_color) pen.setWidth(1) painter.setPen(pen) painter.drawRect(base_rect.adjusted(0, 0, -pen.width(), -pen.width())) painter.restore() return pm
class Callout(QGraphicsItem): def __init__(self, chart): super().__init__(chart) self.m_chart = chart self.m_text = "" self.m_textRect = QRectF() self.m_rect = QRectF() self.m_anchor = QPointF() self.m_font = QFont() def boundingRect(self): anchor = self.mapFromParent(self.m_chart.mapToPosition(self.m_anchor)) rect = QRectF() rect.setLeft(min(self.m_rect.left(), anchor.x())) rect.setRight(max(self.m_rect.right(), anchor.x())) rect.setTop(min(self.m_rect.top(), anchor.y())) rect.setBottom(max(self.m_rect.bottom(), anchor.y())) return rect def paint(self, painter, option, widget=None): path = QPainterPath() path.addRoundedRect(self.m_rect, 5, 5) anchor = self.mapFromParent(self.m_chart.mapToPosition(self.m_anchor)) if not self.m_rect.contains(anchor): point1 = QPointF() point2 = QPointF() # establish the position of the anchor point in relation to m_rect above = anchor.y() <= self.m_rect.top() aboveCenter = (anchor.y() > self.m_rect.top() and anchor.y() <= self.m_rect.center().y()) belowCenter = (anchor.y() > self.m_rect.center().y() and anchor.y() <= self.m_rect.bottom()) below = anchor.y() > self.m_rect.bottom() onLeft = anchor.x() <= self.m_rect.left() leftOfCenter = (anchor.x() > self.m_rect.left() and anchor.x() <= self.m_rect.center().x()) rightOfCenter = (anchor.x() > self.m_rect.center().x() and anchor.x() <= self.m_rect.right()) onRight = anchor.x() > self.m_rect.right() # get the nearest m_rect corner. x = (onRight + rightOfCenter) * self.m_rect.width() y = (below + belowCenter) * self.m_rect.height() cornerCase = ((above and onLeft) or (above and onRight) or (below and onLeft) or (below and onRight)) vertical = abs(anchor.x() - x) > abs(anchor.y() - y) x1 = (x + leftOfCenter * 10 - rightOfCenter * 20 + cornerCase * int(not vertical) * (onLeft * 10 - onRight * 20)) y1 = (y + aboveCenter * 10 - belowCenter * 20 + cornerCase * int(vertical) * (above * 10 - below * 20)) point1.setX(x1) point1.setY(y1) x2 = (x + leftOfCenter * 20 - rightOfCenter * 10 + cornerCase * int(not vertical) * (onLeft * 20 - onRight * 10)) y2 = (y + aboveCenter * 20 - belowCenter * 10 + cornerCase * int(vertical) * (above * 20 - below * 10)) point2.setX(x2) point2.setY(y2) path.moveTo(point1) path.lineTo(anchor) path.lineTo(point2) path = path.simplified() painter.setBrush(QColor(255, 255, 255)) painter.drawPath(path) painter.drawText(self.m_textRect, self.m_text) def mousePressEvent(self, event): event.setAccepted(True) def mouseMoveEvent(self, event): if event.buttons() & Qt.LeftButton: self.setPos( self.mapToParent(event.pos() - event.buttonDownPos(Qt.LeftButton))) event.setAccepted(True) else: event.setAccepted(False) def setText(self, text): self.m_text = text metrics = QFontMetrics(self.m_font) self.m_textRect = QRectF( metrics.boundingRect(QRect(0, 0, 150, 150), Qt.AlignLeft, self.m_text)) self.m_textRect.translate(5, 5) self.prepareGeometryChange() self.m_rect = self.m_textRect.adjusted(-5, -5, 5, 5) def setAnchor(self, point): self.m_anchor = point def updateGeometry(self): self.prepareGeometryChange() self.setPos( self.m_chart.mapToPosition(self.m_anchor) + QPoint(10, -50))