DeepFaceLive/xlib/qt/widgets/QXFixedLayeredImages.py
2021-12-07 17:51:23 +04:00

82 lines
2.2 KiB
Python

from typing import List, Union
import numpy as np
from PyQt6.QtCore import *
from PyQt6.QtGui import *
from PyQt6.QtWidgets import *
from ..gui.from_np import QImage_from_np
from .QXWidget import QXWidget
class QXFixedLayeredImages(QXWidget):
"""
A widget to show multiple stacked images in fixed area
all images must have the same aspect ratio
"""
def __init__(self, fwidth, height):
super().__init__()
self._fwidth = fwidth
self._height = height
self._qp = QPainter()
self._images : List = []
def clear_images(self):
self._images : List = []
self.update()
def add_image(self, image, name=None):
"""
image QImage
QPixmap
np.ndarray of uint8 dtype
"""
saved_ref = None
if not isinstance(image, QImage) and not isinstance(image, QPixmap):
if isinstance(image, np.ndarray):
saved_ref = image
image = QImage_from_np(image)
else:
raise ValueError(f'Unsupported type of image {image.__class__}')
self._images.append( (image, saved_ref) )
self.update()
def sizeHint(self):
return QSize(self._fwidth, self._height)
def paintEvent(self, event):
super().paintEvent(event)
qp = self._qp
qp.begin(self)
qp.setRenderHint(QPainter.RenderHint.SmoothPixmapTransform)
w = self._fwidth
h = self._height
w_half = w /2
h_half = h /2
a = w/h
for image, _ in self._images:
size = image.size()
ap = size.width() / size.height()
if ap > a:
ph_fit = h * (a / ap)
rect = QRect(0, h_half-ph_fit/2, w, ph_fit )
elif ap < a:
pw_fit = w * (ap / a)
rect = QRect(w_half-pw_fit/2, 0, pw_fit, h )
else:
rect = self.rect()
if isinstance(image, QImage):
qp.drawImage(rect, image, image.rect())
elif isinstance(image, QPixmap):
qp.drawPixmap(rect, image, image.rect())
qp.end()