def setObjectText(self, strng): """ TOWRITE :param `strng`: TOWRITE :type `strng`: QString """ self.objText = strng textPath = QPainterPath() font = QFont() font.setFamily(self.objTextFont) font.setPointSizeF(self.objTextSize) font.setBold(self.objTextBold) font.setItalic(self.objTextItalic) font.setUnderline(self.objTextUnderline) font.setStrikeOut(self.objTextStrikeOut) font.setOverline(self.objTextOverline) textPath.addText(0., 0., font, strng) # Translate the path based on the justification. jRect = textPath.boundingRect() # QRectF if self.objTextJustify == "Left": textPath.translate(-jRect.left(), 0) elif self.objTextJustify == "Center": textPath.translate(-jRect.center().x(), 0) elif self.objTextJustify == "Right": textPath.translate(-jRect.right(), 0) elif self.objTextJustify == "Aligned": pass # TODO: TextSingleObject Aligned Justification elif self.objTextJustify == "Middle": textPath.translate(-jRect.center()) elif self.objTextJustify == "Fit": pass # TODO: TextSingleObject Fit Justification elif self.objTextJustify == "Top Left": textPath.translate(-jRect.topLeft()) elif self.objTextJustify == "Top Center": textPath.translate(-jRect.center().x(), -jRect.top()) elif self.objTextJustify == "Top Right": textPath.translate(-jRect.topRight()) elif self.objTextJustify == "Middle Left": textPath.translate(-jRect.left(), -jRect.top() / 2.0) elif self.objTextJustify == "Middle Center": textPath.translate(-jRect.center().x(), -jRect.top() / 2.0) elif self.objTextJustify == "Middle Right": textPath.translate(-jRect.right(), -jRect.top() / 2.0) elif self.objTextJustify == "Bottom Left": textPath.translate(-jRect.bottomLeft()) elif self.objTextJustify == "Bottom Center": textPath.translate(-jRect.center().x(), -jRect.bottom()) elif self.objTextJustify == "Bottom Right": textPath.translate(-jRect.bottomRight()) # Backward or Upside Down. if self.objTextBackward or self.objTextUpsideDown: horiz = 1.0 # qreal vert = 1.0 # qreal if self.objTextBackward: horiz = -1.0 if self.objTextUpsideDown: vert = -1.0 flippedPath = QPainterPath() element = QPainterPath.Element P2 = QPainterPath.Element P3 = QPainterPath.Element P4 = QPainterPath.Element for i in range(0, textPath.elementCount( )): # for(int i = 0; i < textPath.elementCount(); ++i) element = textPath.elementAt(i) if element.isMoveTo(): flippedPath.moveTo(horiz * element.x, vert * element.y) elif element.isLineTo(): flippedPath.lineTo(horiz * element.x, vert * element.y) elif element.isCurveTo(): # start point P1 is not needed P2 = textPath.elementAt(i) # control point P3 = textPath.elementAt(i + 1) # control point P4 = textPath.elementAt(i + 2) # end point flippedPath.cubicTo(horiz * P2.x, vert * P2.y, horiz * P3.x, vert * P3.y, horiz * P4.x, vert * P4.y) objTextPath = flippedPath else: objTextPath = textPath # Add the grip point to the shape path. gripPath = objTextPath # QPainterPath gripPath.connectPath(objTextPath) gripPath.addRect(-0.00000001, -0.00000001, 0.00000002, 0.00000002) self.setObjectPath(gripPath)
class Bar(QToolBar): clicked = Signal(str) def __init__(self, orientation=Qt.Horizontal, parent=None): super().__init__(parent) self.setOrientation(orientation) policy = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed, QSizePolicy.ButtonBox) policy.setHeightForWidth(True) policy.setWidthForHeight(True) self.setSizePolicy(policy) self.setFloatable(False) self.setToolTip("""<p><b>Goto Letter</b></p> <p>Left-click a letter to navigate to the first entry starting with that letter.</p> <p>Right-click a letter to navigate to the first entry starting with the most recently left-clicked letter, plus any subsequent right-clicked letters, and this letter.</p> <p>(One left-click or a fifth right-click clears the previous letters.)</p> <p>For example, left-click <i>S</i> to go to the first “s” entry. Then right-click <i>A</i> to go to the first “sa” entry, then right-click <i>T</i> to go to the first “sat” entry.</p>""") self.timer = QTimer(self) self.timer.setSingleShot(True) self.timer.timeout.connect(self.onTimeout) size = self.font().pointSizeF() strategy = QFont.StyleStrategy(QFont.PreferOutline | QFont.PreferAntialias | QFont.PreferQuality) self.mainFont = QFont("courier new") self.mainFont.setFixedPitch(True) self.mainFont.setStyleStrategy(strategy) self.mainFont.setStyleHint(QFont.Monospace) self.mainFont.setPointSizeF(size * 1.5) self.mainFont.setBold(True) self.mainFont.setItalic(False) self.setFont(self.mainFont) self.smallFont = QFont("helvetica") self.smallFont.setStyleStrategy(strategy) self.smallFont.setStyleHint(QFont.Times) self.smallFont.setPointSizeF(size * 1.25) self.smallFont.setBold(False) self.smallFont.setItalic(False) self.letters = string.ascii_uppercase self.word = None def sizeHint(self): return self.minimumSizeHint() def minimumSizeHint(self): count = len(self.letters) widthAll = self.fontMetrics().width(self.letters) * H_GAP_PC widthW = self.fontMetrics().width("WW") heightOne = self.fontMetrics().height() if self.orientation == Qt.Vertical: return QSize(widthW, (heightOne * count) + HANDLE_OFFSET) return QSize(widthAll + HANDLE_OFFSET, heightOne * V_GAP_PC) def paintEvent(self, event): super().paintEvent(event) letterPen = QPen(Qt.darkGreen if self.isEnabled() else Qt.lightGray) wordPen = QPen(Qt.darkCyan if self.isEnabled() else Qt.lightGray) painter = QPainter(self) painter.setRenderHints(QPainter.TextAntialiasing) painter.setPen(letterPen) heightOne = self.fontMetrics().height() widthOne = self.fontMetrics().width("W") if self.orientation == Qt.Vertical: y = HANDLE_OFFSET for c in self.letters: rect = QRectF(X_OFFSET, y, widthOne, heightOne) painter.drawText(rect, Qt.AlignCenter, c) y += heightOne if self.word is not None: painter.setFont(self.smallFont) painter.setPen(wordPen) rect = self.rect().adjusted(0, HANDLE_OFFSET, -widthOne / 3, 0) painter.drawText(rect, Qt.AlignTop | Qt.AlignRight | Qt.TextWordWrap, "\n".join(self.word.lower())) painter.setPen(letterPen) painter.setFont(self.mainFont) else: widthOne *= H_GAP_PC x = HANDLE_OFFSET for c in self.letters: rect = QRectF(x, 0, widthOne, heightOne * V_GAP_PC) painter.drawText(rect, Qt.AlignCenter, c) x += widthOne if self.word is not None: painter.setFont(self.smallFont) painter.setPen(wordPen) rect = self.rect().adjusted(HANDLE_OFFSET, 0, 0, 0) painter.drawText(rect, Qt.AlignBottom | Qt.AlignLeft, self.word.lower()) painter.setPen(letterPen) painter.setFont(self.mainFont) def mousePressEvent(self, event): if self.orientation == Qt.Vertical: if event.y() < HANDLE_OFFSET: event.ignore() return heightOne = self.fontMetrics().height() i = clamp(0, int((event.y() - HANDLE_OFFSET) / heightOne), len(self.letters) - 1) else: if event.x() < HANDLE_OFFSET: event.ignore() return widthOne = self.fontMetrics().width("W") * H_GAP_PC i = clamp(0, int((event.x() - HANDLE_OFFSET) / widthOne), len(self.letters) - 1) event.accept() word = self.letters[i] if event.button() == Qt.LeftButton or self.word is None: self.word = word elif event.button() == Qt.RightButton: if len(self.word) >= 4: self.word = word elif self.word is not None: self.word += word if self.word is not None: self.clicked.emit(self.word.lower()) self.timer.start(10000) self.update() def contextMenuEvent(self, event): if ((self.orientation == Qt.Vertical and event.y() < HANDLE_OFFSET) or (self.orientation == Qt.Horizontal and event.x() < HANDLE_OFFSET)): event.ignore() else: event.accept() def setOrientation(self, orientation): self.orientation = orientation self.update() def heightForWidth(self, width): count = len(self.letters) heightOne = self.fontMetrics().height() widthAll = self.fontMetrics().width(self.letters) * H_GAP_PC if widthAll > width: # Needs to be vertical return heightOne * count return heightOne * V_GAP_PC # Needs to be horizontal def onTimeout(self): self.timer.stop() if self.word is not None: self.word = None self.update()
class WidgetLcd(QWidget): WEIGHT_CURRENT = 1 WEIGHT_VALUE = 4 WEIGHT_RANGE = 1 WEIGHT_SCALE = 0.5 WEIGHT_BAR = 0.1 WEIGHT_MARGIN = 0.1 TICKS = 22 def __init__(self, parent): QWidget.__init__(self, parent) self._fontCurrent = QFont('Monospace', self.WEIGHT_CURRENT * 10) self._fontValue = QFont('Monospace', self.WEIGHT_VALUE * 10) self._fontRange = QFont('Monospace', self.WEIGHT_RANGE * 10) self._fontScale = QFont('Monospace', self.WEIGHT_SCALE * 10) self.setFont(self._fontCurrent) self._sizeCurrent = self.fontMetrics().tightBoundingRect('#') self.setFont(self._fontValue) self._sizeValue = self.fontMetrics().tightBoundingRect( '-#########. ###') self.setFont(self._fontRange) self._sizeRange = self.fontMetrics().tightBoundingRect('#') self.setFont(self._fontScale) self._sizeScale = self.fontMetrics().tightBoundingRect('##') self.setMinimumWidth(self._sizeValue.width()) self.setMinimumHeight(self._sizeValue.width() / 5) self._meter = None def paintEvent(self, event): width = event.rect().width() - 1 scale = float(width) / self._sizeValue.width() self._fontCurrent.setPointSizeF(scale * self.WEIGHT_CURRENT * 10) self._fontValue.setPointSizeF(scale * self.WEIGHT_VALUE * 10) self._fontRange.setPointSizeF(scale * self.WEIGHT_RANGE * 10) painter = QPainter() painter.begin(self) painter.setPen(QPen(QColor(42, 67, 107), 4 * scale)) pos = self.__drawText(painter, scale) pos = self.__drawBar(painter, scale, width, pos) painter.end() self.setMinimumHeight(pos) def __drawText(self, painter, scale): margin = self._sizeCurrent.height() * self.WEIGHT_MARGIN * 10 * scale top = self._sizeCurrent.height() * scale + margin middle = top + (self._sizeValue.height() * scale) + margin bottom = middle + (self._sizeRange.height() * scale) + margin if self._meter is not None and self._meter.display is not None: if self._meter.current == Meter.CURRENT_DC: current = 'DC' elif self._meter.current == Meter.CURRENT_AC: current = 'AC' else: current = '' painter.setFont(self._fontCurrent) painter.drawText(margin, top, current) painter.setFont(self._fontValue) painter.drawText(margin, middle, self._meter.display) if self._meter.auto: rang = 'AUTO' else: rang = 'MANUAL' painter.setFont(self._fontRange) painter.drawText(margin, bottom, rang) else: painter.setFont(self._fontValue) painter.drawText(margin, middle, ' ------') return bottom + margin def __drawBar(self, painter, scale, width, pos): margin = self._sizeCurrent.height() * self.WEIGHT_MARGIN * 10 * scale height = self._sizeCurrent.height() * self.WEIGHT_BAR * 10 * scale self._fontScale.setPointSizeF(scale * self.WEIGHT_SCALE * 10) painter.setFont(self._fontScale) for i in range(self.TICKS * 2 - 1): x = (i * (width - margin) / float(self.TICKS * 2)) + margin length = height / 2 if i % 10 == 0: length = height centre = self.fontMetrics().width(str(i / 2)) / 2 painter.drawText(x - centre, pos + margin * 2, str(i / 2)) elif i % 2 == 0: length = height * 2 / 3 if self._meter is not None and i <= self._meter.bar: painter.drawLine(x, pos + height, x, pos + height - length) return pos + height + margin * 2 def set(self, meter): self._meter = meter self.repaint() def clear(self): self._meter = None self.repaint()
def setObjectText(self, strng): """ TOWRITE :param `strng`: TOWRITE :type `strng`: QString """ self.objText = strng textPath = QPainterPath() font = QFont() font.setFamily(self.objTextFont) font.setPointSizeF(self.objTextSize) font.setBold(self.objTextBold) font.setItalic(self.objTextItalic) font.setUnderline(self.objTextUnderline) font.setStrikeOut(self.objTextStrikeOut) font.setOverline(self.objTextOverline) textPath.addText(0., 0., font, strng) # Translate the path based on the justification. jRect = textPath.boundingRect() # QRectF if self.objTextJustify == "Left": textPath.translate(-jRect.left(), 0) elif self.objTextJustify == "Center": textPath.translate(-jRect.center().x(), 0) elif self.objTextJustify == "Right": textPath.translate(-jRect.right(), 0) elif self.objTextJustify == "Aligned": pass # TODO: TextSingleObject Aligned Justification elif self.objTextJustify == "Middle": textPath.translate(-jRect.center()) elif self.objTextJustify == "Fit": pass # TODO: TextSingleObject Fit Justification elif self.objTextJustify == "Top Left": textPath.translate(-jRect.topLeft()) elif self.objTextJustify == "Top Center": textPath.translate(-jRect.center().x(), -jRect.top()) elif self.objTextJustify == "Top Right": textPath.translate(-jRect.topRight()) elif self.objTextJustify == "Middle Left": textPath.translate(-jRect.left(), -jRect.top()/2.0) elif self.objTextJustify == "Middle Center": textPath.translate(-jRect.center().x(), -jRect.top()/2.0) elif self.objTextJustify == "Middle Right": textPath.translate(-jRect.right(), -jRect.top()/2.0) elif self.objTextJustify == "Bottom Left": textPath.translate(-jRect.bottomLeft()) elif self.objTextJustify == "Bottom Center": textPath.translate(-jRect.center().x(), -jRect.bottom()) elif self.objTextJustify == "Bottom Right": textPath.translate(-jRect.bottomRight()) # Backward or Upside Down. if self.objTextBackward or self.objTextUpsideDown: horiz = 1.0 # qreal vert = 1.0 # qreal if self.objTextBackward: horiz = -1.0 if self.objTextUpsideDown: vert = -1.0 flippedPath = QPainterPath() element = QPainterPath.Element P2 = QPainterPath.Element P3 = QPainterPath.Element P4 = QPainterPath.Element for i in range(0, textPath.elementCount()): # for(int i = 0; i < textPath.elementCount(); ++i) element = textPath.elementAt(i) if element.isMoveTo(): flippedPath.moveTo(horiz * element.x, vert * element.y) elif element.isLineTo(): flippedPath.lineTo(horiz * element.x, vert * element.y) elif element.isCurveTo(): # start point P1 is not needed P2 = textPath.elementAt(i) # control point P3 = textPath.elementAt(i + 1) # control point P4 = textPath.elementAt(i + 2) # end point flippedPath.cubicTo(horiz * P2.x, vert * P2.y, horiz * P3.x, vert * P3.y, horiz * P4.x, vert * P4.y) objTextPath = flippedPath else: objTextPath = textPath # Add the grip point to the shape path. gripPath = objTextPath # QPainterPath gripPath.connectPath(objTextPath) gripPath.addRect(-0.00000001, -0.00000001, 0.00000002, 0.00000002) self.setObjectPath(gripPath)
class DefaultCustomDelegate(QStyledItemDelegate): '''Delegate to do custom draw of the items''' memoized_size = {} def __init__(self, parent): '''Initialization''' QStyledItemDelegate.__init__(self, parent) self.bg_color = QColor('#000000') self.bg_alternate_color = QColor('#333333') self.new_bg_color = QColor('#0044dd') self.new_bg_alternate_color = QColor('#223399') self.user_color = QColor('#7AB4F5') self.time_color = QColor('#7AB4F5') self.replyto_color = QColor('#7AB4F5') self.text_color = QColor('#FFFFFF') self.separator_color = QColor('#000000') self.fsize = 1.0 self.fm = None self.minifm = None self.normFont = None self.miniFont = None # print os.path.join(os.path.dirname(__file__), # 'icons', 'reply.png') self.reply_icon = QPixmap(os.path.join(os.path.dirname(__file__), 'icons', 'reply.png')) # print dir(self.reply_icon) self.retweet_icon = QPixmap(os.path.join(os.path.dirname(__file__), 'icons', 'retweet.png')) self.geoloc_icon = QPixmap(os.path.join(os.path.dirname(__file__), 'icons', 'geoloc.png')) def doZoomRefresh(self): self.memoized_size.clear() self.fm = None self.minifm = None self.normFont = None self.miniFont = None def sizeHint(self, option, index): '''Custom size calculation of our items''' uid = to_str(index.data(role=IDROLE)) + 'x' + str(option.rect.width()) #Fix Bug #967 (sometime uid have some strange unicode chars ... ?) try: return self.memoized_size[uid] except: tweet = to_str(index.data(Qt.DisplayRole)) # One time is enought sizeHint need to be fast if not self.fm: self.normFont = QFont(option.font) self.normFont.setPointSizeF(option.font.pointSizeF() * self.fsize) self.fm = QFontMetrics(self.normFont) if not self.minifm: self.miniFont = QFont(option.font) self.miniFont.setPointSizeF(option.font.pointSizeF() * 0.8 * self.fsize) self.minifm = QFontMetrics(self.miniFont) height = self.fm.boundingRect( 0, 0, option.rect.width() - 75, 800, int(Qt.AlignTop) | int(Qt.AlignLeft) | int(Qt.TextWordWrap), tweet, ).height() reply_text = to_str(index.data(role=REPLYTEXTROLE)) if reply_text: height += self.minifm.boundingRect( 0, 0, option.rect.width() - 75, 800, int(Qt.AlignTop) | int(Qt.AlignLeft) | int(Qt.TextWordWrap), reply_text, ).height() + 5 height += self.minifm.boundingRect( 0, 0, option.rect.width() - 75, 800, int(Qt.AlignTop) | int(Qt.AlignLeft) | int(Qt.TextWordWrap), 'LpqAT', ).height() height += 10 # Spacer if height < 70: height = 70 self.memoized_size[uid] = QSize(option.rect.width(), height) return self.memoized_size[uid] def paint( self, painter, option, index, ): '''Paint our tweet''' (x1, y1, x2, y2) = option.rect.getCoords() # Ugly hack ? if y1 < 0 and y2 < 0: return # Init Font : One time is enough if not self.fm: self.normFont = QFont(option.font) self.normFont.setPointSizeF(option.font.pointSizeF() * self.fsize) if not self.minifm: self.miniFont = QFont(option.font) self.miniFont.setPointSizeF(option.font.pointSizeF() * 0.8 * self.fsize) # Query data tweet = to_str(index.data(Qt.DisplayRole)) screenname = to_str(index.data(SCREENNAMEROLE)) retweet_of = index.data(RETWEETOFROLE) timestamp = to_str(index.data(role=TIMESTAMPROLE)) reply_name = to_str(index.data(role=REPLYTOSCREENNAMEROLE)) reply_text = to_str(index.data(role=REPLYTEXTROLE)) is_new = index.data(role=ISNEWROLE) painter.save() # Draw alternate ? if index.row() % 2 == 0: color = self.bg_color else: color = self.bg_alternate_color painter.fillRect(option.rect, color) # highlight selected items if option.state & QStyle.State_Selected: painter.fillRect(option.rect, option.palette.highlight()) # Draw icon icon = index.data(Qt.DecorationRole) if type(icon) == QPixmap: try: painter.drawPixmap(x1 + 10, y1 + 10, 50, 50, icon) except Exception: logging.exception("Drawing icon") # Draw screenname painter.setFont(self.miniFont) painter.setPen(self.user_color) nrect = painter.drawText(option.rect.adjusted(70, 5, -4, -9), int(Qt.AlignTop) | int(Qt.AlignLeft), screenname) # Reply icon if reply_name: painter.drawPixmap(x1 + 74 + nrect.width(), y1, 26, 26, self.reply_icon) painter.setFont(self.miniFont) painter.setPen(self.replyto_color) painter.drawText(option.rect.adjusted(109 + nrect.width(), 5, -4, -9), int(Qt.AlignTop) | int(Qt.AlignLeft), reply_name) # Retweet icon if retweet_of: painter.drawPixmap(x1 + 74 + nrect.width(), y1, 32, 32, self.retweet_icon) painter.setFont(self.miniFont) painter.setPen(self.replyto_color) painter.drawText(option.rect.adjusted(110 + nrect.width(), 5, -4, -9), int(Qt.AlignTop) | int(Qt.AlignLeft), retweet_of.user.screen_name) # Draw tweet painter.setFont(self.normFont) painter.setPen(self.text_color) new_rect = painter.drawText(option.rect.adjusted(70, nrect.height() + 5, -4, 0), int(Qt.AlignTop) | int(Qt.AlignLeft) | int(Qt.TextWordWrap), tweet) # Draw Timeline painter.setFont(self.miniFont) painter.setPen(self.time_color) painter.drawText(option.rect.adjusted(70, 5, -4, -9), int(Qt.AlignTop) | int(Qt.AlignRight), timestamp) # Draw reply if reply_text: painter.setFont(self.miniFont) painter.setPen(self.replyto_color) painter.drawText(option.rect.adjusted(70, nrect.height() + new_rect.height() + 5, -4, -9), int(Qt.AlignTop) | int(Qt.AlignLeft) | int(Qt.TextWordWrap), reply_text) # Draw line separator painter.setPen(self.separator_color) painter.drawLine(x1, y2, x2, y2) #Use a little tips to say that's a new tweet if is_new: painter.fillRect(x1,y1,8,y2, self.new_bg_alternate_color) # restore painter painter.restore()
class DefaultCustomDelegate(QStyledItemDelegate): '''Delegate to do custom draw of the items''' memoized_size = {} def __init__(self, parent): '''Initialization''' QStyledItemDelegate.__init__(self, parent) self.bg_color = QColor('#000000') self.bg_alternate_color = QColor('#333333') self.new_bg_color = QColor('#0044dd') self.new_bg_alternate_color = QColor('#223399') self.user_color = QColor('#7AB4F5') self.time_color = QColor('#7AB4F5') self.replyto_color = QColor('#7AB4F5') self.text_color = QColor('#FFFFFF') self.separator_color = QColor('#000000') self.fsize = 1.0 self.fm = None self.minifm = None self.normFont = None self.miniFont = None # print os.path.join(os.path.dirname(__file__), # 'icons', 'reply.png') self.reply_icon = QPixmap( os.path.join(os.path.dirname(__file__), 'icons', 'reply.png')) # print dir(self.reply_icon) self.retweet_icon = QPixmap( os.path.join(os.path.dirname(__file__), 'icons', 'retweet.png')) self.geoloc_icon = QPixmap( os.path.join(os.path.dirname(__file__), 'icons', 'geoloc.png')) def doZoomRefresh(self): self.memoized_size.clear() self.fm = None self.minifm = None self.normFont = None self.miniFont = None def sizeHint(self, option, index): '''Custom size calculation of our items''' uid = to_str(index.data(role=IDROLE)) + 'x' + str(option.rect.width( )) #Fix Bug #967 (sometime uid have some strange unicode chars ... ?) try: return self.memoized_size[uid] except: tweet = to_str(index.data(Qt.DisplayRole)) # One time is enought sizeHint need to be fast if not self.fm: self.normFont = QFont(option.font) self.normFont.setPointSizeF(option.font.pointSizeF() * self.fsize) self.fm = QFontMetrics(self.normFont) if not self.minifm: self.miniFont = QFont(option.font) self.miniFont.setPointSizeF(option.font.pointSizeF() * 0.8 * self.fsize) self.minifm = QFontMetrics(self.miniFont) height = self.fm.boundingRect( 0, 0, option.rect.width() - 75, 800, int(Qt.AlignTop) | int(Qt.AlignLeft) | int(Qt.TextWordWrap), tweet, ).height() reply_text = to_str(index.data(role=REPLYTEXTROLE)) if reply_text: height += self.minifm.boundingRect( 0, 0, option.rect.width() - 75, 800, int(Qt.AlignTop) | int(Qt.AlignLeft) | int(Qt.TextWordWrap), reply_text, ).height() + 5 height += self.minifm.boundingRect( 0, 0, option.rect.width() - 75, 800, int(Qt.AlignTop) | int(Qt.AlignLeft) | int(Qt.TextWordWrap), 'LpqAT', ).height() height += 10 # Spacer if height < 70: height = 70 self.memoized_size[uid] = QSize(option.rect.width(), height) return self.memoized_size[uid] def paint( self, painter, option, index, ): '''Paint our tweet''' (x1, y1, x2, y2) = option.rect.getCoords() # Ugly hack ? if y1 < 0 and y2 < 0: return # Init Font : One time is enough if not self.fm: self.normFont = QFont(option.font) self.normFont.setPointSizeF(option.font.pointSizeF() * self.fsize) if not self.minifm: self.miniFont = QFont(option.font) self.miniFont.setPointSizeF(option.font.pointSizeF() * 0.8 * self.fsize) # Query data tweet = to_str(index.data(Qt.DisplayRole)) screenname = to_str(index.data(SCREENNAMEROLE)) retweet_of = index.data(RETWEETOFROLE) timestamp = to_str(index.data(role=TIMESTAMPROLE)) reply_name = to_str(index.data(role=REPLYTOSCREENNAMEROLE)) reply_text = to_str(index.data(role=REPLYTEXTROLE)) is_new = index.data(role=ISNEWROLE) painter.save() # Draw alternate ? if index.row() % 2 == 0: color = self.bg_color else: color = self.bg_alternate_color painter.fillRect(option.rect, color) # highlight selected items if option.state & QStyle.State_Selected: painter.fillRect(option.rect, option.palette.highlight()) # Draw icon icon = index.data(Qt.DecorationRole) if type(icon) == QPixmap: try: painter.drawPixmap(x1 + 10, y1 + 10, 50, 50, icon) except Exception: logging.exception("Drawing icon") # Draw screenname painter.setFont(self.miniFont) painter.setPen(self.user_color) nrect = painter.drawText(option.rect.adjusted(70, 5, -4, -9), int(Qt.AlignTop) | int(Qt.AlignLeft), screenname) # Reply icon if reply_name: painter.drawPixmap(x1 + 74 + nrect.width(), y1, 26, 26, self.reply_icon) painter.setFont(self.miniFont) painter.setPen(self.replyto_color) painter.drawText( option.rect.adjusted(109 + nrect.width(), 5, -4, -9), int(Qt.AlignTop) | int(Qt.AlignLeft), reply_name) # Retweet icon if retweet_of: painter.drawPixmap(x1 + 74 + nrect.width(), y1, 32, 32, self.retweet_icon) painter.setFont(self.miniFont) painter.setPen(self.replyto_color) painter.drawText( option.rect.adjusted(110 + nrect.width(), 5, -4, -9), int(Qt.AlignTop) | int(Qt.AlignLeft), retweet_of.user.screen_name) # Draw tweet painter.setFont(self.normFont) painter.setPen(self.text_color) new_rect = painter.drawText( option.rect.adjusted(70, nrect.height() + 5, -4, 0), int(Qt.AlignTop) | int(Qt.AlignLeft) | int(Qt.TextWordWrap), tweet) # Draw Timeline painter.setFont(self.miniFont) painter.setPen(self.time_color) painter.drawText(option.rect.adjusted(70, 5, -4, -9), int(Qt.AlignTop) | int(Qt.AlignRight), timestamp) # Draw reply if reply_text: painter.setFont(self.miniFont) painter.setPen(self.replyto_color) painter.drawText( option.rect.adjusted(70, nrect.height() + new_rect.height() + 5, -4, -9), int(Qt.AlignTop) | int(Qt.AlignLeft) | int(Qt.TextWordWrap), reply_text) # Draw line separator painter.setPen(self.separator_color) painter.drawLine(x1, y2, x2, y2) #Use a little tips to say that's a new tweet if is_new: painter.fillRect(x1, y1, 8, y2, self.new_bg_alternate_color) # restore painter painter.restore()