aboutsummaryrefslogtreecommitdiff
path: root/src/preview_thread.py
blob: fb3b79286a01e60560b21e5b9ff4b9118d50bd6c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
'''
    Thread that runs to create QImages for MainWindow's preview label.
    Processes a queue of component lists.
'''
from PyQt5 import QtCore, QtGui, uic
from PyQt5.QtCore import pyqtSignal, pyqtSlot
from PIL import Image
from PIL.ImageQt import ImageQt
import core
from queue import Queue, Empty
import os

from frame import FloodFrame


class Worker(QtCore.QObject):

    imageCreated = pyqtSignal(['QImage'])
    error = pyqtSignal()

    def __init__(self, parent=None, queue=None):
        QtCore.QObject.__init__(self)
        parent.newTask.connect(self.createPreviewImage)
        parent.processTask.connect(self.process)
        self.parent = parent
        self.core = self.parent.core
        self.queue = queue
        self.width = int(self.core.settings.value('outputWidth'))
        self.height = int(self.core.settings.value('outputHeight'))

        # create checkerboard background to represent transparency
        self.background = FloodFrame(1920, 1080, (0, 0, 0, 0))
        self.background.paste(Image.open(os.path.join(
            self.core.wd, "background.png")))

    @pyqtSlot(list)
    def createPreviewImage(self, components):
        dic = {
          "components": components,
        }
        self.queue.put(dic)

    @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

            if self.background.width != self.width:
                self.background = self.background.resize(
                    (self.width, self.height))
            frame = self.background.copy()

            components = nextPreviewInformation["components"]
            for component in reversed(components):
                try:
                    frame = Image.alpha_composite(
                        frame, component.previewRender(self)
                    )

                except ValueError as e:
                    errMsg = "Bad frame returned by %s's preview renderer. " \
                        "%s. This is a fatal error." % (
                            str(component), str(e).capitalize()
                        )
                    print(errMsg)
                    self.parent.showMessage(
                        msg=errMsg,
                        detail=str(e),
                        icon='Warning',
                        parent=None  # MainWindow is in a different thread
                    )
                    self.error.emit()
                    break
            else:
                self.imageCreated.emit(QtGui.QImage(ImageQt(frame)))

        except Empty:
            True