diff options
Diffstat (limited to 'src/avp/gui/preview_thread.py')
| -rw-r--r-- | src/avp/gui/preview_thread.py | 93 |
1 files changed, 93 insertions, 0 deletions
diff --git a/src/avp/gui/preview_thread.py b/src/avp/gui/preview_thread.py new file mode 100644 index 0000000..1d78516 --- /dev/null +++ b/src/avp/gui/preview_thread.py @@ -0,0 +1,93 @@ +""" +Thread that runs to create QImages for MainWindow's preview label. +Processes a queue of component lists. +""" + +from PyQt6 import QtCore, QtGui, uic +from PyQt6.QtCore import pyqtSignal, pyqtSlot +from PIL import Image +from PIL.ImageQt import ImageQt +from queue import Queue, Empty +import os +import logging + +from ..toolkit.frame import Checkerboard +from ..toolkit import disableWhenOpeningProject + + +log = logging.getLogger("AVP.Gui.PreviewThread") + + +class Worker(QtCore.QObject): + + imageCreated = pyqtSignal(QtGui.QImage) + error = pyqtSignal(str) + + def __init__(self, core, settings, queue): + super().__init__() + self.core = core + self.settings = settings + width = int(self.settings.value("outputWidth")) + height = int(self.settings.value("outputHeight")) + self.queue = queue + self.background = Checkerboard(width, height) + + @disableWhenOpeningProject + @pyqtSlot(list) + def createPreviewImage(self, components): + dic = { + "components": components, + } + self.queue.put(dic) + log.debug("Preview thread id: {}".format(int(QtCore.QThread.currentThreadId()))) + + @pyqtSlot() + def process(self): + try: + nextPreviewInformation = self.queue.get(block=False) + while self.queue.qsize() >= 2: + try: + self.queue.get(block=False) + except Empty: + continue + width = int(self.settings.value("outputWidth")) + height = int(self.settings.value("outputHeight")) + if self.background.width != width or self.background.height != height: + self.background = Checkerboard(width, height) + + frame = self.background.copy() + log.info("Creating new preview frame") + components = nextPreviewInformation["components"] + for component in reversed(components): + try: + component.lockSize(width, height) + newFrame = component.previewRender() + component.unlockSize() + frame = Image.alpha_composite(frame, newFrame) + + except ValueError as e: + errMsg = ( + "Bad frame returned by %s's preview renderer. " + "%s. New frame size was %s*%s; should be %s*%s." + % ( + str(component), + str(e).capitalize(), + newFrame.width, + newFrame.height, + width, + height, + ) + ) + log.critical(errMsg) + self.error.emit(errMsg) + break + except RuntimeError as e: + log.error(str(e)) + else: + # We must store a reference to this QImage + # or else Qt will garbage-collect it on the C++ side + self.frame = ImageQt(frame) + self.imageCreated.emit(QtGui.QImage(self.frame)) + + except Empty: + True |
