class ScalingImage(QWidget): """Изображение, которое масштабируется вместе с родительским объектом, сохраняя пропорции.""" def __init__(self, parent=None): QWidget.__init__(self, parent=parent) self.pix_map = QPixmap() def setPixmap(self, pix_map): """Задать картинку.""" self.pix_map = pix_map self.update() def paintEvent(self, event): """Метод отвечает за отрисовку картинки.""" if not self.pix_map.isNull(): painter = QPainter(self) painter.setRenderHint(QPainter.SmoothPixmapTransform) width, height = self.width(), self.height() image_width = self.pix_map.size().width() image_height = self.pix_map.size().height() ratio = min(width, height) / max(image_width, image_height) new_image_width = image_width * ratio new_image_height = image_height * ratio rect = QRect((width - new_image_width) // 2, (height - new_image_height) // 2, new_image_width, new_image_height) painter.drawPixmap(rect, self.pix_map)
class ScalingImage(QWidget): """Изображение, которое масштабируется вместе с родительским объектом, сохраняя пропорции.""" def __init__(self, parent=None): QWidget.__init__(self, parent=parent) self.pix_map = QPixmap() self.image_rect = QRect() def setPixmap(self, pix_map): """Задать картинку.""" self.pix_map = pix_map self.update() def paintEvent(self, event): """Метод отвечает за отрисовку картинки.""" if not self.pix_map.isNull(): painter = QPainter(self) painter.setRenderHint(QPainter.SmoothPixmapTransform) width, height = self.width(), self.height() # Из-за бага в PyQt5 (как я понял) высота виджета определяется # меньше действительной и изображение получается меньше. Чтобы # исправить это, высота умножается на определённое число, # вычисленное методом проб и ошибок if width > height: height *= 1.34 image_width = self.pix_map.size().width() image_height = self.pix_map.size().height() ratio = min(width, height) / max(image_width, image_height) new_image_width = image_width * ratio new_image_height = image_height * ratio rect = QRect((width - new_image_width) // 2, (self.height() - new_image_height) // 2, new_image_width, new_image_height) self.image_rect = rect painter.drawPixmap(rect, self.pix_map)
class CoverView(QWidget): def __init__(self, parent=None): QWidget.__init__(self, parent) self.current_pixmap_size = QSize(0, 0) self.pixmap = QPixmap() self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) def set_pixmap(self, data): self.pixmap.loadFromData(data) self.current_pixmap_size = self.pixmap.size() self.update() def paintEvent(self, event): if self.pixmap.isNull(): return canvas_size = self.rect() width = self.current_pixmap_size.width() extrax = canvas_size.width() - width if extrax < 0: extrax = 0 x = int(extrax / 2.0) height = self.current_pixmap_size.height() extray = canvas_size.height() - height if extray < 0: extray = 0 y = int(extray / 2.0) target = QRect(x, y, min(canvas_size.width(), width), min(canvas_size.height(), height)) p = QPainter(self) p.setRenderHints(QPainter.Antialiasing | QPainter.SmoothPixmapTransform) p.drawPixmap(target, self.pixmap.scaled(target.size(), Qt.KeepAspectRatio, Qt.SmoothTransformation)) p.end() def sizeHint(self): return QSize(300, 400)
class ImageBox(QWidget): def __init__(self): super(ImageBox, self).__init__() self.img = None self.scaled_img = None self.point = QPoint(0, 0) self.start_pos = None self.end_pos = None self.left_click = False self.scale = 1 self.SR_flag = False def init_ui(self): self.setWindowTitle("ImageBox") def set_image(self, img_path): """ open image file :param img_path: image file path :return: """ self.img = QPixmap(img_path) if self.SR_flag: self.scaled_img = self.img.scaled(self.size(), Qt.KeepAspectRatio, Qt.FastTransformation) self.SR_flag = False else: self.scaled_img = self.img.scaled(self.img.size(), Qt.KeepAspectRatio, Qt.FastTransformation) def paintEvent(self, e): if self.scaled_img: painter = QPainter() painter.begin(self) painter.scale(self.scale, self.scale) painter.drawPixmap(self.point, self.scaled_img) painter.end() def mouseMoveEvent(self, e): if self.left_click: self.end_pos = e.pos() - self.start_pos self.point = self.point + self.end_pos self.start_pos = e.pos() self.repaint() def mousePressEvent(self, e): if e.button() == Qt.LeftButton: self.left_click = True self.start_pos = e.pos() def mouseReleaseEvent(self, e): if e.button() == Qt.LeftButton: self.left_click = False
class CoverView(QWidget): def __init__(self, parent=None): QWidget.__init__(self, parent) self.current_pixmap_size = QSize(0, 0) self.pixmap = QPixmap() self.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding) def set_pixmap(self, data): self.pixmap.loadFromData(data) self.current_pixmap_size = self.pixmap.size() self.update() def paintEvent(self, event): if self.pixmap.isNull(): return canvas_size = self.rect() width = self.current_pixmap_size.width() extrax = canvas_size.width() - width if extrax < 0: extrax = 0 x = int(extrax / 2.) height = self.current_pixmap_size.height() extray = canvas_size.height() - height if extray < 0: extray = 0 y = int(extray / 2.) target = QRect(x, y, min(canvas_size.width(), width), min(canvas_size.height(), height)) p = QPainter(self) p.setRenderHints(QPainter.RenderHint.Antialiasing | QPainter.RenderHint.SmoothPixmapTransform) p.drawPixmap( target, self.pixmap.scaled(target.size(), Qt.AspectRatioMode.KeepAspectRatio, Qt.TransformationMode.SmoothTransformation)) p.end() def sizeHint(self): return QSize(300, 400)
def paint(self, painter, option, index): if not self.parent().indexWidget(index): # 创建控件 widget = QLabel(self.parent()) widget.resize(self.sizeCache) layout = QHBoxLayout() widget.setLayout(layout) widget.setObjectName("QTableViewDelegate") # 创建缩略图 path = index.data() pixmap = QPixmap(path) lbl = QLabel(widget) lbl.resize(pixmap.size()) lbl.setPixmap(pixmap) # 将缩略图标签加入到控件中(为了居中...使用了两层控件) layout.addWidget(lbl) # 设置控件 self.parent().setIndexWidget(index, widget)
class ProjectThumbnail(QWidget): def __init__(self): super().__init__() self._pixmap = None self._setup_ui() def _setup_ui(self): self._pixmap = QPixmap('') self.setFixedSize(self._pixmap.size()) def paintEvent(self, event): painter = QPainter(self) painter.setRenderHint(QPainter.Antialiasing) painter.drawPixmap(0, 0, self._pixmap) painter.fillRect(self.rect(), self.palette().midlight().color()) round_path = QPainterPath() round_path.addRoundedRect(0, 0, self.width(), self.height(), 5, 5) sq_path = QPainterPath() sq_path.addRect(0, 0, 10, self.height()) draw_path = sq_path - round_path painter.setPen(Qt.NoPen) painter.setBrush(self.palette().dark().color()) painter.drawPath(draw_path)
class ImageView(QWidget, ImageDropMixin): BORDER_WIDTH = 1 cover_changed = pyqtSignal(object) def __init__(self, parent=None, show_size_pref_name=None, default_show_size=False): QWidget.__init__(self, parent) self.show_size_pref_name = ( 'show_size_on_cover_' + show_size_pref_name) if show_size_pref_name else None self._pixmap = QPixmap() self.setMinimumSize(QSize(150, 200)) ImageDropMixin.__init__(self) self.draw_border = True self.show_size = False if self.show_size_pref_name: self.show_size = gprefs.get(self.show_size_pref_name, default_show_size) def setPixmap(self, pixmap): if not isinstance(pixmap, QPixmap): raise TypeError('Must use a QPixmap') self._pixmap = pixmap self.updateGeometry() self.update() def build_context_menu(self): m = ImageDropMixin.build_context_menu(self) if self.show_size_pref_name: text = _('Hide size in corner') if self.show_size else _( 'Show size in corner') m.addAction(text, self.toggle_show_size) return m def toggle_show_size(self): self.show_size ^= True if self.show_size_pref_name: gprefs[self.show_size_pref_name] = self.show_size self.update() def pixmap(self): return self._pixmap def sizeHint(self): if self._pixmap.isNull(): return self.minimumSize() return self._pixmap.size() def paintEvent(self, event): QWidget.paintEvent(self, event) pmap = self._pixmap if pmap.isNull(): return w, h = pmap.width(), pmap.height() ow, oh = w, h cw, ch = self.rect().width(), self.rect().height() scaled, nw, nh = fit_image(w, h, cw, ch) if scaled: pmap = pmap.scaled(int(nw * pmap.devicePixelRatio()), int(nh * pmap.devicePixelRatio()), Qt.IgnoreAspectRatio, Qt.SmoothTransformation) w, h = int(pmap.width() / pmap.devicePixelRatio()), int( pmap.height() / pmap.devicePixelRatio()) x = int(abs(cw - w) / 2) y = int(abs(ch - h) / 2) target = QRect(x, y, w, h) p = QPainter(self) p.setRenderHints(QPainter.Antialiasing | QPainter.SmoothPixmapTransform) p.drawPixmap(target, pmap) if self.draw_border: pen = QPen() pen.setWidth(self.BORDER_WIDTH) p.setPen(pen) p.drawRect(target) if self.show_size: draw_size(p, target, ow, oh) p.end()
class ImageView(QWidget, ImageDropMixin): BORDER_WIDTH = 1 cover_changed = pyqtSignal(object) def __init__(self, parent=None, show_size_pref_name=None, default_show_size=False): QWidget.__init__(self, parent) self.show_size_pref_name = ('show_size_on_cover_' + show_size_pref_name) if show_size_pref_name else None self._pixmap = QPixmap() self.setMinimumSize(QSize(150, 200)) ImageDropMixin.__init__(self) self.draw_border = True self.show_size = False if self.show_size_pref_name: self.show_size = gprefs.get(self.show_size_pref_name, default_show_size) def setPixmap(self, pixmap): if not isinstance(pixmap, QPixmap): raise TypeError('Must use a QPixmap') self._pixmap = pixmap self.updateGeometry() self.update() def build_context_menu(self): m = ImageDropMixin.build_context_menu(self) if self.show_size_pref_name: text = _('Hide size in corner') if self.show_size else _('Show size in corner') m.addAction(text, self.toggle_show_size) return m def toggle_show_size(self): self.show_size ^= True if self.show_size_pref_name: gprefs[self.show_size_pref_name] = self.show_size self.update() def pixmap(self): return self._pixmap def sizeHint(self): if self._pixmap.isNull(): return self.minimumSize() return self._pixmap.size() def paintEvent(self, event): QWidget.paintEvent(self, event) pmap = self._pixmap if pmap.isNull(): return w, h = pmap.width(), pmap.height() ow, oh = w, h cw, ch = self.rect().width(), self.rect().height() scaled, nw, nh = fit_image(w, h, cw, ch) if scaled: pmap = pmap.scaled(int(nw*pmap.devicePixelRatio()), int(nh*pmap.devicePixelRatio()), Qt.IgnoreAspectRatio, Qt.SmoothTransformation) w, h = int(pmap.width()/pmap.devicePixelRatio()), int(pmap.height()/pmap.devicePixelRatio()) x = int(abs(cw - w)/2.) y = int(abs(ch - h)/2.) target = QRect(x, y, w, h) p = QPainter(self) p.setRenderHints(QPainter.Antialiasing | QPainter.SmoothPixmapTransform) p.drawPixmap(target, pmap) if self.draw_border: pen = QPen() pen.setWidth(self.BORDER_WIDTH) p.setPen(pen) p.drawRect(target) if self.show_size: draw_size(p, target, ow, oh) p.end()
class ImageView(QWidget, ImageDropMixin): # {{{ BORDER_WIDTH = 1 cover_changed = pyqtSignal(object) def __init__(self, parent=None, show_size_pref_name=None, default_show_size=False): QWidget.__init__(self, parent) self.show_size_pref_name = ( 'show_size_on_cover_' + show_size_pref_name) if show_size_pref_name else None self._pixmap = QPixmap() self.setMinimumSize(QSize(150, 200)) ImageDropMixin.__init__(self) self.draw_border = True self.show_size = False if self.show_size_pref_name: self.show_size = gprefs.get(self.show_size_pref_name, default_show_size) def setPixmap(self, pixmap): if not isinstance(pixmap, QPixmap): raise TypeError('Must use a QPixmap') self._pixmap = pixmap self.updateGeometry() self.update() def build_context_menu(self): m = ImageDropMixin.build_context_menu(self) if self.show_size_pref_name: text = _('Hide size in corner') if self.show_size else _( 'Show size in corner') m.addAction(text, self.toggle_show_size) return m def toggle_show_size(self): self.show_size ^= True if self.show_size_pref_name: gprefs[self.show_size_pref_name] = self.show_size self.update() def pixmap(self): return self._pixmap def sizeHint(self): if self._pixmap.isNull(): return self.minimumSize() return self._pixmap.size() def paintEvent(self, event): QWidget.paintEvent(self, event) pmap = self._pixmap if pmap.isNull(): return w, h = pmap.width(), pmap.height() ow, oh = w, h cw, ch = self.rect().width(), self.rect().height() scaled, nw, nh = fit_image(w, h, cw, ch) if scaled: pmap = pmap.scaled(nw, nh, Qt.IgnoreAspectRatio, Qt.SmoothTransformation) w, h = pmap.width(), pmap.height() x = int(abs(cw - w) / 2.) y = int(abs(ch - h) / 2.) target = QRect(x, y, w, h) p = QPainter(self) p.setRenderHints(QPainter.Antialiasing | QPainter.SmoothPixmapTransform) p.drawPixmap(target, pmap) if self.draw_border: pen = QPen() pen.setWidth(self.BORDER_WIDTH) p.setPen(pen) p.drawRect(target) if self.show_size: sztgt = target.adjusted(0, 0, 0, -4) f = p.font() f.setBold(True) p.setFont(f) sz = u'\u00a0%d x %d\u00a0' % (ow, oh) flags = Qt.AlignBottom | Qt.AlignRight | Qt.TextSingleLine szrect = p.boundingRect(sztgt, flags, sz) p.fillRect(szrect.adjusted(0, 0, 0, 4), QColor(0, 0, 0, 200)) p.setPen(QPen(QColor(255, 255, 255))) p.drawText(sztgt, flags, sz) p.end()
class ImageView(QWidget, ImageDropMixin): # {{{ BORDER_WIDTH = 1 cover_changed = pyqtSignal(object) def __init__(self, parent=None, show_size_pref_name=None, default_show_size=False): QWidget.__init__(self, parent) self.show_size_pref_name = ('show_size_on_cover_' + show_size_pref_name) if show_size_pref_name else None self._pixmap = QPixmap() self.setMinimumSize(QSize(150, 200)) ImageDropMixin.__init__(self) self.draw_border = True self.show_size = False if self.show_size_pref_name: self.show_size = gprefs.get(self.show_size_pref_name, default_show_size) def setPixmap(self, pixmap): if not isinstance(pixmap, QPixmap): raise TypeError('Must use a QPixmap') self._pixmap = pixmap self.updateGeometry() self.update() def build_context_menu(self): m = ImageDropMixin.build_context_menu(self) if self.show_size_pref_name: text = _('Hide size in corner') if self.show_size else _('Show size in corner') m.addAction(text, self.toggle_show_size) return m def toggle_show_size(self): self.show_size ^= True if self.show_size_pref_name: gprefs[self.show_size_pref_name] = self.show_size self.update() def pixmap(self): return self._pixmap def sizeHint(self): if self._pixmap.isNull(): return self.minimumSize() return self._pixmap.size() def paintEvent(self, event): QWidget.paintEvent(self, event) pmap = self._pixmap if pmap.isNull(): return w, h = pmap.width(), pmap.height() ow, oh = w, h cw, ch = self.rect().width(), self.rect().height() scaled, nw, nh = fit_image(w, h, cw, ch) if scaled: pmap = pmap.scaled(nw, nh, Qt.IgnoreAspectRatio, Qt.SmoothTransformation) w, h = pmap.width(), pmap.height() x = int(abs(cw - w)/2.) y = int(abs(ch - h)/2.) target = QRect(x, y, w, h) p = QPainter(self) p.setRenderHints(QPainter.Antialiasing | QPainter.SmoothPixmapTransform) p.drawPixmap(target, pmap) if self.draw_border: pen = QPen() pen.setWidth(self.BORDER_WIDTH) p.setPen(pen) p.drawRect(target) if self.show_size: sztgt = target.adjusted(0, 0, 0, -4) f = p.font() f.setBold(True) p.setFont(f) sz = u'\u00a0%d x %d\u00a0'%(ow, oh) flags = Qt.AlignBottom|Qt.AlignRight|Qt.TextSingleLine szrect = p.boundingRect(sztgt, flags, sz) p.fillRect(szrect.adjusted(0, 0, 0, 4), QColor(0, 0, 0, 200)) p.setPen(QPen(QColor(255,255,255))) p.drawText(sztgt, flags, sz) p.end()