def load(self, name, size = 128, forceCache = False): icon = QIcon() size = int(size) self.pixmap = QPixmap() if not type(name) in (list, tuple): name = [str(name)] if forceCache or self._forceCache: for _name in name: for _size in self.iconSizes: if (QPixmapCache.find('$qt'+str(_name)+str(_size), self.pixmap)): logging.debug('Icon %s returned from cache' % _name) return self.pixmap logging.debug('Getting icon : %s size: %s' % (','.join(name), size)) pix = self.findIcon(name, size) if pix.isNull(): for _size in self.iconSizes: pix = self.findIcon(name, _size) if not pix.isNull(): if size == _size: return pix icon.addPixmap(pix) if icon.isNull(): return self.pixmap return icon.pixmap(QSize(size, size)) return pix
def findIcon(self, name=str, size=int): for _name in name: pixmapName = ''.join(('$qt', str(_name), str(size))) self.pixmap = QPixmapCache.find(pixmapName) if (self.pixmap): logging.debug('Icon %s returned from cache' % _name) return self.pixmap self._themes = [] if self.themeName: self._themes.append(self.themeName) for _name in name: self.pixmap = self.findIconHelper(int(size), self.themeName, _name) if not self.pixmap.isNull(): break if self.pixmap.isNull(): for _name in name: self._themes.extend(self.themeIndex.parents) if len(self._themes) > 0: self.pixmap = self.findIconHelper(int(size), self._themes[0], _name) if not self.pixmap.isNull(): break if not name: return QPixmap() pixmapName = ''.join(('$qt', str(_name), str(size))) if not self.pixmap.isNull(): logging.debug('Icon cached with name: %s ' % pixmapName) QPixmapCache.insert(pixmapName, self.pixmap) return self.pixmap
def load(self, name, size=128, forceCache=False): icon = QIcon() size = int(size) self.pixmap = QPixmap() if not type(name) in (list, tuple): name = [str(name)] if forceCache or self._forceCache: for _name in name: for _size in self.iconSizes: self.pixmap = QPixmapCache.find('$qt' + str(_name) + str(_size)) if (self.pixmap): logging.debug('Icon %s returned from cache' % _name) return self.pixmap logging.debug('Getting icon : %s size: %s' % (','.join(name), size)) pix = self.findIcon(name, size) if pix.isNull(): for _size in self.iconSizes: pix = self.findIcon(name, _size) if not pix.isNull(): if size == _size: return pix icon.addPixmap(pix) if icon.isNull(): return self.pixmap return icon.pixmap(QSize(size, size)) return pix
def __init__(self, weboob, backend, person, parent=None): super(MiniPerson, self).__init__(parent) self.parent = parent self.ui = Ui_MiniPerson() self.ui.setupUi(self) self.weboob = weboob self.backend = backend self.person = person self.ui.nameLabel.setText('%s' % person.name) if not empty(person.short_description): if self.parent.ui.currentActionLabel.text().startswith('Casting'): self.ui.shortDescTitleLabel.setText(u'Role') self.ui.shortDescLabel.setText('%s' % person.short_description) else: self.ui.shortDescTitleLabel.hide() self.ui.shortDescLabel.hide() self.ui.backendButton.setText(backend.name) minfo = self.weboob.repositories.get_module_info(backend.NAME) icon_path = self.weboob.repositories.get_module_icon_path(minfo) if icon_path: pixmap = QPixmapCache.find(icon_path) if not pixmap: pixmap = QPixmap(QImage(icon_path)) self.ui.backendButton.setIcon(QIcon(pixmap)) self.ui.newTabButton.clicked.connect(self.newTabPressed) self.ui.viewButton.clicked.connect(self.viewPressed) self.ui.viewThumbnailButton.clicked.connect(self.gotThumbnail) if self.parent.parent.ui.showTCheck.isChecked(): self.gotThumbnail()
def __init__(self, weboob, backend, songlyrics, parent=None): super(MiniSonglyrics, self).__init__(parent) self.parent = parent self.ui = Ui_MiniSonglyrics() self.ui.setupUi(self) self.weboob = weboob self.backend = backend self.songlyrics = songlyrics self.ui.titleLabel.setText(songlyrics.title) if not empty(songlyrics.artist): if len(songlyrics.artist) > 300: self.ui.artistLabel.setText('%s [...]'%songlyrics.artist[:300]) else: self.ui.artistLabel.setText(songlyrics.artist) else: self.ui.artistLabel.setText('') self.ui.backendButton.setText(backend.name) minfo = self.weboob.repositories.get_module_info(backend.NAME) icon_path = self.weboob.repositories.get_module_icon_path(minfo) if icon_path: pixmap = QPixmapCache.find(icon_path) if not pixmap: pixmap = QPixmap(QImage(icon_path)) self.ui.backendButton.setIcon(QIcon(pixmap)) self.ui.newTabButton.clicked.connect(self.newTabPressed) self.ui.viewButton.clicked.connect(self.viewPressed)
def __init__(self, weboob, backend, movie, parent=None): super(MiniMovie, self).__init__(parent) self.parent = parent self.ui = Ui_MiniMovie() self.ui.setupUi(self) self.weboob = weboob self.backend = backend self.movie = movie self.ui.titleLabel.setText(movie.original_title) self.ui.shortDescLabel.setText(movie.short_description) self.ui.backendButton.setText(backend.name) minfo = self.weboob.repositories.get_module_info(backend.NAME) icon_path = self.weboob.repositories.get_module_icon_path(minfo) if icon_path: pixmap = QPixmapCache.find(icon_path) if not pixmap: pixmap = QPixmap(QImage(icon_path)) self.ui.backendButton.setIcon(QIcon(pixmap)) self.ui.newTabButton.clicked.connect(self.newTabPressed) self.ui.viewButton.clicked.connect(self.viewPressed) self.ui.viewThumbnailButton.clicked.connect(self.gotThumbnail) if self.parent.parent.ui.showTCheck.isChecked(): self.gotThumbnail()
def __init__(self, weboob, backend, torrent, parent=None): super(MiniTorrent, self).__init__(parent) self.parent = parent self.ui = Ui_MiniTorrent() self.ui.setupUi(self) self.weboob = weboob self.backend = backend self.torrent = torrent self.ui.nameLabel.setText(torrent.name) if not empty(torrent.seeders) and not empty(torrent.leechers): self.ui.seedLeechLabel.setText('%s/%s' % (torrent.seeders, torrent.leechers)) if not empty(torrent.size): self.ui.sizeLabel.setText(u'%s' % sizeof_fmt(torrent.size)) self.ui.backendButton.setText(backend.name) minfo = self.weboob.repositories.get_module_info(backend.NAME) icon_path = self.weboob.repositories.get_module_icon_path(minfo) if icon_path: pixmap = QPixmapCache.find(icon_path) if not pixmap: pixmap = QPixmap(QImage(icon_path)) self.ui.backendButton.setIcon(QIcon(pixmap)) self.ui.newTabButton.clicked.connect(self.newTabPressed) self.ui.viewButton.clicked.connect(self.viewPressed)
def __init__(self, weboob, backend, recipe, parent=None): super(MiniRecipe, self).__init__(parent) self.parent = parent self.ui = Ui_MiniRecipe() self.ui.setupUi(self) self.weboob = weboob self.backend = backend self.recipe = recipe self.ui.titleLabel.setText(recipe.title) if not empty(recipe.short_description): if len(recipe.short_description) > 300: self.ui.shortDescLabel.setText('%s [...]'%recipe.short_description[:300]) else: self.ui.shortDescLabel.setText(recipe.short_description) else: self.ui.shortDescLabel.setText('') self.ui.backendButton.setText(backend.name) minfo = self.weboob.repositories.get_module_info(backend.NAME) icon_path = self.weboob.repositories.get_module_icon_path(minfo) if icon_path: pixmap = QPixmapCache.find(icon_path) if not pixmap: pixmap = QPixmap(QImage(icon_path)) self.ui.backendButton.setIcon(QIcon(pixmap)) self.ui.newTabButton.clicked.connect(self.newTabPressed) self.ui.viewButton.clicked.connect(self.viewPressed) self.ui.viewThumbnailButton.clicked.connect(self.gotThumbnail) if self.parent.parent.ui.showTCheck.isChecked(): self.gotThumbnail()
def __init__(self, weboob, backend, recipe, parent=None): super(MiniRecipe, self).__init__(parent) self.parent = parent self.ui = Ui_MiniRecipe() self.ui.setupUi(self) self.weboob = weboob self.backend = backend self.recipe = recipe self.ui.titleLabel.setText(recipe.title) if not empty(recipe.short_description): if len(recipe.short_description) > 300: self.ui.shortDescLabel.setText('%s [...]' % recipe.short_description[:300]) else: self.ui.shortDescLabel.setText(recipe.short_description) else: self.ui.shortDescLabel.setText('') self.ui.backendButton.setText(backend.name) minfo = self.weboob.repositories.get_module_info(backend.NAME) icon_path = self.weboob.repositories.get_module_icon_path(minfo) if icon_path: pixmap = QPixmapCache.find(icon_path) if not pixmap: pixmap = QPixmap(QImage(icon_path)) self.ui.backendButton.setIcon(QIcon(pixmap)) self.ui.newTabButton.clicked.connect(self.newTabPressed) self.ui.viewButton.clicked.connect(self.viewPressed) self.ui.viewThumbnailButton.clicked.connect(self.gotThumbnail) if self.parent.parent.ui.showTCheck.isChecked(): self.gotThumbnail()
def __init__(self, weboob, backend, songlyrics, parent=None): super(MiniSonglyrics, self).__init__(parent) self.parent = parent self.ui = Ui_MiniSonglyrics() self.ui.setupUi(self) self.weboob = weboob self.backend = backend self.songlyrics = songlyrics self.ui.titleLabel.setText(songlyrics.title) if not empty(songlyrics.artist): if len(songlyrics.artist) > 300: self.ui.artistLabel.setText('%s [...]' % songlyrics.artist[:300]) else: self.ui.artistLabel.setText(songlyrics.artist) else: self.ui.artistLabel.setText('') self.ui.backendButton.setText(backend.name) minfo = self.weboob.repositories.get_module_info(backend.NAME) icon_path = self.weboob.repositories.get_module_icon_path(minfo) if icon_path: pixmap = QPixmapCache.find(icon_path) if not pixmap: pixmap = QPixmap(QImage(icon_path)) self.ui.backendButton.setIcon(QIcon(pixmap)) self.ui.newTabButton.clicked.connect(self.newTabPressed) self.ui.viewButton.clicked.connect(self.viewPressed)
def findIcon(self, name = str, size = int): for _name in name: pixmapName = ''.join(('$qt', str(_name), str(size))) if (QPixmapCache.find(pixmapName, self.pixmap)): logging.debug('Icon %s returned from cache' % _name) return self.pixmap self._themes = [] if self.themeName: self._themes.append(self.themeName) for _name in name: self.pixmap = self.findIconHelper(int(size), self.themeName, _name) if not self.pixmap.isNull(): break if self.pixmap.isNull(): for _name in name: self._themes.extend(self.themeIndex.parents) if len(self._themes) > 0: self.pixmap = self.findIconHelper(int(size), self._themes[0] ,_name) if not self.pixmap.isNull(): break if not name: return QPixmap() pixmapName = ''.join(('$qt', str(_name), str(size))) if not self.pixmap.isNull(): logging.debug('Icon cached with name: %s ' % pixmapName) QPixmapCache.insert(pixmapName, self.pixmap) return self.pixmap
def find_or_get(path): pixmap = QPixmapCache.find(path) if pixmap is None: pixmap = QPixmap(path) QPixmapCache.insert(path, pixmap) return pixmap return pixmap
def pixmap(self): if not self.p: key = "%s%s%s" % (self.barcode["value"], self.barcode["type"], self.barcode["res"]) if not QPixmapCache.find(key): self._createBarcode() if self.barcode["valid"]: key = "%s%s%s" % (self.barcode["value"], self.barcode["type"], self.barcode["res"]) if key: QPixmapCache.insert(key, self.p) else: self.p = QPixmapCache.find(key) self.barcode["valid"] = True if not self.p: self.barcode["valid"] = False return self.p
def paint(self, painter: QtGui.QPainter, option: QStyleOptionViewItem, index: QtCore.QModelIndex) -> None: item_size = option.rect.size() custom_decoration_w, custom_decoration_h = index.data( SlideListModel.DecorationSizeOrRatioRole) if option.decorationPosition == QStyleOptionViewItem.Left: text_x, text_y = custom_decoration_w + self.icon_and_text_spacing, 0 text_width = item_size.width( ) - custom_decoration_w - self.icon_and_text_spacing text_height = custom_decoration_h elif option.decorationPosition == QStyleOptionViewItem.Top: text_size = super().sizeHint(option, index) custom_decoration_h = custom_decoration_h - text_size.height() text_x, text_y = 0, custom_decoration_h + self.icon_and_text_spacing text_width = custom_decoration_w text_height = item_size.height( ) - custom_decoration_h - self.icon_and_text_spacing slide_view_params: SlideViewParams = index.data( SlideListModel.SlideViewParamsRole) scene_rect = QRectF(*slide_view_params.level_rect) img_key = "{}_{}_{}".format(custom_decoration_w, custom_decoration_h, slide_view_params.cache_key()) icon_pixmap = QPixmapCache.find(img_key) if icon_pixmap is None: slide_helper = SlideHelper(slide_view_params.slide_path) # print("read", img_key) scene = QGraphicsScene() # t1 = elapsed() # print("before slide_graphics", t1) slide_graphics = SlideGraphicsGroup(slide_view_params) # t2 = elapsed() # print("slide_graphics", t2 - t1) scene.clear() scene.invalidate() scene.addItem(slide_graphics) slide_graphics.update_visible_level(slide_view_params.level) scene.setSceneRect( slide_helper.get_rect_for_level(slide_view_params.level)) image = build_screenshot_image( scene, QSize(custom_decoration_w, custom_decoration_h), scene_rect) # t3 = elapsed() # print("build_screenshot_image", t3 - t2) icon_pixmap = QtGui.QPixmap.fromImage(image) QPixmapCache.insert(img_key, icon_pixmap) # t4 = elapsed() painter.fillRect(option.rect, painter.background()) painter.drawPixmap(option.rect.topLeft(), icon_pixmap) # painter.drawRect(option.rect) painter.drawRect(option.rect.topLeft().x(), option.rect.topLeft().y(), icon_pixmap.width(), icon_pixmap.height()) option.rect = option.rect.translated(text_x, text_y) option.rect.setSize(QSize(text_width, text_height)) super().paint(painter, option, index)
def paint(self, painter: QPainter, option: QStyleOptionGraphicsItem, widget: QWidget): self.pixmap = QPixmapCache.find(self.cache_key) if not self.pixmap: with openslide.open_slide(self.slide_path) as slide: tile_pilimage = slide.read_region( (self.slide_rect_0.x(), self.slide_rect_0.y()), self.level, (self.slide_rect_0.width(), self.slide_rect_0.height()), ) self.pixmap = self.pilimage_to_pixmap(tile_pilimage) # self.pixmap.fill(Qt.red) QPixmapCache.insert(self.cache_key, self.pixmap) painter.drawPixmap(self.boundingRect().toRect(), self.pixmap)
def verticalGradient(painter: QPainter, spanRect: QRect, clipRect: QRect): keyColor = BASE_COLOR key = "verticalGradient %d %d %d %d %d" % (spanRect.width( ), spanRect.height(), clipRect.width(), clipRect.height(), keyColor.rgb()) pixmap = QPixmapCache.find(key) if pixmap is None: pixmap = QPixmap(clipRect.size()) p = QPainter(pixmap) rect = QRect(0, 0, clipRect.width(), clipRect.height()) verticalGradientHelper(p, spanRect, rect) p.end() QPixmapCache.insert(key, pixmap) painter.drawPixmap(clipRect.topLeft(), pixmap)
def paint(self, painter: QtGui.QPainter, option: QStyleOptionGraphicsItem, widget: typing.Optional[QWidget] = ...): # print("pos ", self.pos()) # print("paint ", self.slide_rect_0, option.rect, option.exposedRect) self.pixmap = QPixmapCache.find(self.cache_key) if not self.pixmap: # print("read", self.slide_rect_0) with openslide.open_slide(self.slide_path) as slide: tile_pilimage = slide.read_region( (self.slide_rect_0.x(), self.slide_rect_0.y()), self.level, (self.slide_rect_0.width(), self.slide_rect_0.height())) self.pixmap = self.pilimage_to_pixmap(tile_pilimage) QPixmapCache.insert(self.cache_key, self.pixmap) # painter.drawPixmap(self.slide_rect_0, self.pixmap) painter.drawPixmap(self.boundingRect().toRect(), self.pixmap)
def addBackends(self, cap=None, entry_all=True, entry_title=False): """ Populate the model by adding backends. Appends backends to the model, without clearing previous entries. For each entry in the model, the cap name is stored under role RoleBackendName and the capability object under role RoleCapability. :param cap: capabilities to add (None to add all loaded caps) :param entry_all: if True, add a "All backends" entry :param entry_title: if True, add a disabled entry with the cap name """ if entry_title: if cap: capname = cap.__name__ else: capname = '(All capabilities)' item = QStandardItem(capname) item.setEnabled(False) self.appendRow(item) first = True for backend in self.weboob.iter_backends(caps=cap): if first and entry_all: item = QStandardItem('(All backends)') item.setData('', self.RoleBackendName) item.setData(cap, self.RoleCapability) self.appendRow(item) first = False item = QStandardItem(backend.name) item.setData(backend.name, self.RoleBackendName) item.setData(cap, self.RoleCapability) minfo = self.weboob.repositories.get_module_info(backend.NAME) icon_path = self.weboob.repositories.get_module_icon_path(minfo) if icon_path: pixmap = QPixmapCache.find(icon_path) if not pixmap: pixmap = QPixmap(QImage(icon_path)) item.setIcon(QIcon(pixmap)) self.appendRow(item)
def slidepath_to_pximap(slidepath, icon_size: QSize): img_key = "{}_{}".format(slidepath, str(icon_size)) icon_pixmap = QPixmapCache.find(img_key) if icon_pixmap is None: # pilimg: Image.Image = Image.open(slidepath) with openslide.open_slide(slidepath) as slide: pilimg = slide.get_thumbnail( (icon_size.width(), icon_size.height())) icon_image = QImage(icon_size, QImage.Format_RGB888) painter = QPainter(icon_image) painter.fillRect(icon_image.rect(), painter.background()) img = ImageQt(pilimg) scaled_icon_image = img.scaled(icon_size, Qt.KeepAspectRatio) p = QPoint((icon_size.width() - scaled_icon_image.width()) / 2, (icon_size.height() - scaled_icon_image.height()) / 2) painter.drawImage(p, scaled_icon_image) painter.end() icon_pixmap = QPixmap.fromImage(icon_image) QPixmapCache.insert(img_key, icon_pixmap) return icon_pixmap
def __init__(self, weboob, backend, subtitle, parent=None): super(MiniSubtitle, self).__init__(parent) self.parent = parent self.ui = Ui_MiniSubtitle() self.ui.setupUi(self) self.weboob = weboob self.backend = backend self.subtitle = subtitle self.ui.nameLabel.setText(subtitle.name) if not empty(subtitle.nb_cd): self.ui.nbcdLabel.setText(u'%s' % subtitle.nb_cd) self.ui.backendButton.setText(backend.name) minfo = self.weboob.repositories.get_module_info(backend.NAME) icon_path = self.weboob.repositories.get_module_icon_path(minfo) if icon_path: pixmap = QPixmapCache.find(icon_path) if not pixmap: pixmap = QPixmap(QImage(icon_path)) self.ui.backendButton.setIcon(QIcon(pixmap)) self.ui.newTabButton.clicked.connect(self.newTabPressed) self.ui.viewButton.clicked.connect(self.viewPressed)
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)
def draw_icon(icon, rect, painter, icon_mode, shadow=False): cache = icon.pixmap(rect.size()) dip_offset = QPoint(1, -2) cache = QPixmap() pixname = "icon {0} {1} {2}".format(icon.cacheKey(), icon_mode, rect.height()) if QPixmapCache.find(pixname) is None: pix = icon.pixmap(rect.size()) device_pixel_ratio = pix.devicePixelRatio() radius = 3 * device_pixel_ratio offset = dip_offset * device_pixel_ratio cache = QPixmap(pix.size() + QSize(radius * 2, radius * 2)) cache.fill(Qt.transparent) cache_painter = QPainter(cache) if icon_mode == QIcon.Disabled: im = pix.toImage().convertToFormat(QImage.Format_ARGB32) for y in range(0, im.height()): scanline = im.scanLine(y) for x in range(0, im.width()): pixel = scanline intensity = qGray(pixel) scanline = qRgba(intensity, intensity, intensity, qAlpha(pixel)) scanline += 1 pix = QPixmap.fromImage(im) # Draw shadow tmp = QImage(pix.size() + QSize(radius * 2, radius * 2), QImage.Format_ARGB32_Premultiplied) tmp.fill(Qt.transparent) tmp_painter = QPainter(tmp) tmp_painter.setCompositionMode(QPainter.CompositionMode_Source) tmp_painter.drawPixmap( QRect(radius, radius, pix.width(), pix.height()), pix) tmp_painter.end() # Blur the alpha channel blurred = QImage(tmp.size(), QImage.Format_ARGB32_Premultiplied) blur_painter = QPainter(blurred) blur_painter.end() # tmp = blurred tmp_painter.begin(tmp) tmp_painter.setCompositionMode(QPainter.CompositionMode_SourceIn) tmp_painter.fillRect(tmp.rect(), QColor(0, 0, 0, 150)) tmp_painter.end() tmp_painter.begin(tmp) tmp_painter.setCompositionMode(QPainter.CompositionMode_SourceIn) tmp_painter.fillRect(tmp.rect(), QColor(0, 0, 0, 150)) tmp_painter.end() # Draw the blurred drop shadow cache_painter.drawImage( QRect(0, 0, cache.rect().width(), cache.rect().height()), tmp) # Draw the actual pixmap cache_painter.drawPixmap( QRect( QPoint(radius, radius) + offset, QSize(pix.width(), pix.height())), pix) cache_painter.end() cache.setDevicePixelRatio(device_pixel_ratio) QPixmapCache.insert(pixname, cache) target_rect = cache.rect() target_rect.setSize(target_rect.size() / cache.devicePixelRatio()) target_rect.moveCenter(rect.center() - dip_offset) painter.drawPixmap(target_rect, cache)
def draw_icon(icon, rect, painter, icon_mode, shadow=False): cache = icon.pixmap(rect.size()) dip_offset = QPoint(1, -2) cache = QPixmap() pixname = "icon {0} {1} {2}".format( icon.cacheKey(), icon_mode, rect.height() ) if QPixmapCache.find(pixname) is None: pix = icon.pixmap(rect.size()) device_pixel_ratio = pix.devicePixelRatio() radius = 3 * device_pixel_ratio offset = dip_offset * device_pixel_ratio cache = QPixmap(pix.size() + QSize(radius * 2, radius * 2)) cache.fill(Qt.transparent) cache_painter = QPainter(cache) if icon_mode == QIcon.Disabled: im = pix.toImage().convertToFormat(QImage.Format_ARGB32) for y in range(0, im.height()): scanline = im.scanLine(y) for x in range(0, im.width()): pixel = scanline intensity = qGray(pixel) scanline = qRgba( intensity, intensity, intensity, qAlpha(pixel)) scanline += 1 pix = QPixmap.fromImage(im) # Draw shadow tmp = QImage(pix.size() + QSize(radius * 2, radius * 2), QImage.Format_ARGB32_Premultiplied) tmp.fill(Qt.transparent) tmp_painter = QPainter(tmp) tmp_painter.setCompositionMode(QPainter.CompositionMode_Source) tmp_painter.drawPixmap( QRect(radius, radius, pix.width(), pix.height()), pix) tmp_painter.end() # Blur the alpha channel blurred = QImage(tmp.size(), QImage.Format_ARGB32_Premultiplied) blur_painter = QPainter(blurred) blur_painter.end() # tmp = blurred tmp_painter.begin(tmp) tmp_painter.setCompositionMode(QPainter.CompositionMode_SourceIn) tmp_painter.fillRect(tmp.rect(), QColor(0, 0, 0, 150)) tmp_painter.end() tmp_painter.begin(tmp) tmp_painter.setCompositionMode(QPainter.CompositionMode_SourceIn) tmp_painter.fillRect(tmp.rect(), QColor(0, 0, 0, 150)) tmp_painter.end() # Draw the blurred drop shadow cache_painter.drawImage( QRect(0, 0, cache.rect().width(), cache.rect().height()), tmp) # Draw the actual pixmap cache_painter.drawPixmap( QRect(QPoint(radius, radius) + offset, QSize(pix.width(), pix.height())), pix) cache_painter.end() cache.setDevicePixelRatio(device_pixel_ratio) QPixmapCache.insert(pixname, cache) target_rect = cache.rect() target_rect.setSize(target_rect.size() / cache.devicePixelRatio()) target_rect.moveCenter(rect.center() - dip_offset) painter.drawPixmap(target_rect, cache)
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)
def drawIconWithShadow(icon: QIcon, rect: QRect, p: QPainter, iconMode: QIcon.Mode = None, dipRadius: int = None, color: QColor = None, dipOffset: QPoint = None): if iconMode is None: iconMode = QIcon.Normal if color is None: color = QColor(0, 0, 0, 130) if dipRadius is None: dipRadius = 3 if dipOffset is None: dipOffset = QPoint(1, -2) devicePixelRatio: int = p.device().devicePixelRatio() pixmapName = "icon %s %s %s %s" % (icon.cacheKey(), iconMode, rect.height(), devicePixelRatio) cache = QPixmapCache.find(pixmapName) if cache is None: # High-dpi support: The in parameters (rect, radius, offset) are in # device-independent pixels. The call to QIcon::pixmap() below might # return a high-dpi pixmap, which will in that case have a devicePixelRatio # different than 1. The shadow drawing caluculations are done in device # pixels. window = p.device().window().windowHandle() px = icon.pixmap(window, rect.size(), iconMode) radius = dipRadius * devicePixelRatio offset = dipOffset * devicePixelRatio cache = QPixmap(px.size() + QSize(radius * 2, radius * 2)) cache.fill(Qt.transparent) cachePainter = QPainter(cache) if iconMode == QIcon.Disabled: hasDisabledState = len(icon.availableSizes()) == len( icon.availableSizes(QIcon.Disabled)) if not hasDisabledState: px = disabledSideBarIcon(icon.pixmap(window, rect.size())) elif TOOLBAR_ICON_SHADOW: # Draw shadow tmp = QImage(px.size() + QSize(radius * 2, radius * 2 + 1), QImage.Format_ARGB32_Premultiplied) tmp.fill(Qt.transparent) tmpPainter = QPainter(tmp) tmpPainter.setCompositionMode(QPainter.CompositionMode_Source) tmpPainter.drawPixmap( QRect(radius, radius, px.width(), px.height()), px) tmpPainter.end() # blur the alpha channel blurred = QImage(tmp.size(), QImage.Format_ARGB32_Premultiplied) blurred.fill(Qt.transparent) blurPainter = QPainter(blurred) #qt_blurImage(blurPainter, tmp, radius, False, True) # implement qt_blurImage via QLabel with QGraphicsBlurEffect # FIXME: alignment is broken scene = QGraphicsScene() item = QGraphicsPixmapItem(QPixmap.fromImage(tmp)) effect = QGraphicsBlurEffect() effect.setBlurRadius(radius) item.setGraphicsEffect(effect) scene.addItem(item) scene.render(blurPainter) blurPainter.end() tmp = blurred # blacken the image... tmpPainter.begin(tmp) tmpPainter.setCompositionMode(QPainter.CompositionMode_SourceIn) tmpPainter.fillRect(tmp.rect(), color) tmpPainter.end() tmpPainter.begin(tmp) tmpPainter.setCompositionMode(QPainter.CompositionMode_SourceIn) tmpPainter.fillRect(tmp.rect(), color) tmpPainter.end() # draw the blurred drop shadow... cachePainter.drawImage( QRect(0, 0, cache.rect().width(), cache.rect().height()), tmp) # Draw the actual pixmap... cachePainter.drawPixmap( QRect( QPoint(radius, radius) + offset, QSize(px.width(), px.height())), px) cachePainter.end() cache.setDevicePixelRatio(devicePixelRatio) QPixmapCache.insert(pixmapName, cache) targetRect = cache.rect() targetRect.setSize(targetRect.size() / cache.devicePixelRatio()) targetRect.moveCenter(rect.center() - dipOffset) p.drawPixmap(targetRect, cache)
def _get_media_pixmap(self, _id, option: 'QStyleOptionViewItem', size: QSize) -> QPixmap: global PIXMAP_CACHE_MISS, PIXMAP_CACHE_HITS pix = QPixmapCache.find(str(_id)) if pix is not None: PIXMAP_CACHE_HITS += 1 return pix PIXMAP_CACHE_MISS += 1 text_url_query = QSqlQuery() text_url_query.prepare( 'select url from MediaLocations where media_id = ? AND url LIKE "data:,%" LIMIT 1;' ) text_url_query.bindValue(0, _id) if not text_url_query.exec(): raise RuntimeError if text_url_query.first(): text = text_url_query.value(0).split('data:,', 1)[1] pix = QPixmap(size) painter = QPainter(pix) c = option.palette.base().color() painter.fillRect(pix.rect(), c) # painter.setFont( QFont("Arial") ); c = option.palette.text().color() painter.setPen(c) painter.drawText( pix.rect().marginsRemoved(QMargins(5, 5, 5, 5)), # Qt.TextWrapAnywhere | Qt.TextJustificationForced, Qt.TextWordWrap, text) else: thumb_query = QSqlQuery() thumb_query.prepare( 'select thumbnail from Thumbnails where media_id = ?;') thumb_query.bindValue(0, _id) if not thumb_query.exec(): raise RuntimeError if not thumb_query.first(): raise KeyError pxb = thumb_query.value(0) if len(pxb) < 10: raise ValueError(len(pxb)) assert isinstance(pxb, QByteArray), type(pxb) # pxd = marshal.loads(zlib.decompress(pxb.data()))['jpeg'] pxd = pxb pix = QPixmap() pix.loadFromData(pxd) pix = pix.scaled(size, Qt.KeepAspectRatioByExpanding) thumb_query.clear() QPixmapCache.insert(str(_id), pix) text_url_query.clear() # print(f'PIXMAP_CACHE_HITS/TOTAL = {PIXMAP_CACHE_HITS/(PIXMAP_CACHE_HITS+PIXMAP_CACHE_MISS):.0%}') return pix