From 282f1c4b12b485a567f0d055832a5bf4409404a3 Mon Sep 17 00:00:00 2001 From: tassaron Date: Sat, 12 Aug 2017 09:44:11 -0400 Subject: [PATCH] move previewWindow class into new file and cache frequently-created blank frames --- src/mainwindow.py | 61 +------------------------------------------ src/preview_win.py | 62 ++++++++++++++++++++++++++++++++++++++++++++ src/toolkit/frame.py | 37 +++++++++++++++++--------- 3 files changed, 88 insertions(+), 72 deletions(-) create mode 100644 src/preview_win.py diff --git a/src/mainwindow.py b/src/mainwindow.py index 114015c..1abb108 100644 --- a/src/mainwindow.py +++ b/src/mainwindow.py @@ -17,6 +17,7 @@ import logging from core import Core import preview_thread +from preview_win import PreviewWindow from presetmanager import PresetManager from toolkit import disableWhenEncoding, disableWhenOpeningProject, checkOutput @@ -24,66 +25,6 @@ from toolkit import disableWhenEncoding, disableWhenOpeningProject, checkOutput log = logging.getLogger('AVP.MainWindow') -class PreviewWindow(QtWidgets.QLabel): - ''' - Paints the preview QLabel and maintains the aspect ratio when the - window is resized. - ''' - log = logging.getLogger('AVP.MainWindow.Preview') - - def __init__(self, parent, img): - super(PreviewWindow, self).__init__() - self.parent = parent - self.setFrameStyle(QtWidgets.QFrame.StyledPanel) - self.pixmap = QtGui.QPixmap(img) - - def paintEvent(self, event): - size = self.size() - painter = QtGui.QPainter(self) - point = QtCore.QPoint(0, 0) - scaledPix = self.pixmap.scaled( - size, - QtCore.Qt.KeepAspectRatio, - transformMode=QtCore.Qt.SmoothTransformation) - - # start painting the label from left upper corner - point.setX((size.width() - scaledPix.width())/2) - point.setY((size.height() - scaledPix.height())/2) - painter.drawPixmap(point, scaledPix) - - def changePixmap(self, img): - self.pixmap = QtGui.QPixmap(img) - self.repaint() - - def mousePressEvent(self, event): - if self.parent.encoding: - return - - i = self.parent.window.listWidget_componentList.currentRow() - if i >= 0: - component = self.parent.core.selectedComponents[i] - if not hasattr(component, 'previewClickEvent'): - self.log.info('Ignored click event') - return - pos = (event.x(), event.y()) - size = (self.width(), self.height()) - butt = event.button() - self.log.info('Click event for #%s: %s button %s' % ( - i, pos, butt)) - component.previewClickEvent( - pos, size, butt - ) - self.parent.core.updateComponent(i) - - @QtCore.pyqtSlot(str) - def threadError(self, msg): - self.parent.showMessage( - msg=msg, - icon='Critical', - parent=self - ) - - class MainWindow(QtWidgets.QMainWindow): ''' The MainWindow wraps many Core methods in order to update the GUI diff --git a/src/preview_win.py b/src/preview_win.py new file mode 100644 index 0000000..40c19c6 --- /dev/null +++ b/src/preview_win.py @@ -0,0 +1,62 @@ +from PyQt5 import QtCore, QtGui, QtWidgets +import logging + + +class PreviewWindow(QtWidgets.QLabel): + ''' + Paints the preview QLabel in MainWindow and maintains the aspect ratio + when the window is resized. + ''' + log = logging.getLogger('AVP.PreviewWindow') + + def __init__(self, parent, img): + super(PreviewWindow, self).__init__() + self.parent = parent + self.setFrameStyle(QtWidgets.QFrame.StyledPanel) + self.pixmap = QtGui.QPixmap(img) + + def paintEvent(self, event): + size = self.size() + painter = QtGui.QPainter(self) + point = QtCore.QPoint(0, 0) + scaledPix = self.pixmap.scaled( + size, + QtCore.Qt.KeepAspectRatio, + transformMode=QtCore.Qt.SmoothTransformation) + + # start painting the label from left upper corner + point.setX((size.width() - scaledPix.width())/2) + point.setY((size.height() - scaledPix.height())/2) + painter.drawPixmap(point, scaledPix) + + def changePixmap(self, img): + self.pixmap = QtGui.QPixmap(img) + self.repaint() + + def mousePressEvent(self, event): + if self.parent.encoding: + return + + i = self.parent.window.listWidget_componentList.currentRow() + if i >= 0: + component = self.parent.core.selectedComponents[i] + if not hasattr(component, 'previewClickEvent'): + self.log.info('Ignored click event') + return + pos = (event.x(), event.y()) + size = (self.width(), self.height()) + butt = event.button() + self.log.info('Click event for #%s: %s button %s' % ( + i, pos, butt)) + component.previewClickEvent( + pos, size, butt + ) + self.parent.core.updateComponent(i) + + @QtCore.pyqtSlot(str) + def threadError(self, msg): + self.parent.showMessage( + msg=msg, + icon='Critical', + parent=self + ) diff --git a/src/toolkit/frame.py b/src/toolkit/frame.py index 02f9229..e4332eb 100644 --- a/src/toolkit/frame.py +++ b/src/toolkit/frame.py @@ -77,27 +77,40 @@ def defaultSize(framefunc): def FloodFrame(width, height, RgbaTuple): + log.debug('Creating new %s*%s %s flood frame' % ( + width, height, + 'blank' if RgbaTuple[3] == 0 else RgbaTuple + ) + ) return Image.new("RGBA", (width, height), RgbaTuple) @defaultSize -def BlankFrame(width, height): +def BlankFrame(width, height, blankFrames={}): '''The base frame used by each component to start drawing.''' - log.debug('Creating new %s*%s blank frame' % (width, height)) - return FloodFrame(width, height, (0, 0, 0, 0)) + try: + return blankFrames[(width, height)] + except KeyError: + newFrame = FloodFrame(width, height, (0, 0, 0, 0)) + blankFrames[(width, height)] = newFrame + return newFrame @defaultSize -def Checkerboard(width, height): +def Checkerboard(width, height, checkerboards={}): ''' A checkerboard to represent transparency to the user. TODO: Would be cool to generate this image with numpy instead. ''' - log.debug('Creating new %s*%s checkerboard' % (width, height)) - image = FloodFrame(1920, 1080, (0, 0, 0, 0)) - image.paste(Image.open( - os.path.join(core.Core.wd, "background.png")), - (0, 0) - ) - image = image.resize((width, height)) - return image + try: + return checkerboards[(width, height)] + except KeyError: + log.debug('Creating new %s*%s checkerboard' % (width, height)) + image = FloodFrame(1920, 1080, (0, 0, 0, 0)) + image.paste(Image.open( + os.path.join(core.Core.wd, "background.png")), + (0, 0) + ) + image = image.resize((width, height)) + checkerboards[(width, height)] = image + return image