fixed issues with undoing relative widgets
This commit is contained in:
parent
87e762a8aa
commit
c07f2426ce
198
src/component.py
198
src/component.py
|
@ -9,6 +9,7 @@ import sys
|
|||
import math
|
||||
import time
|
||||
import logging
|
||||
from copy import copy
|
||||
|
||||
from toolkit.frame import BlankFrame
|
||||
from toolkit import (
|
||||
|
@ -113,14 +114,20 @@ class ComponentMetaclass(type(QtCore.QObject)):
|
|||
|
||||
def presetWrapper(self, *args):
|
||||
with openingPreset(self):
|
||||
return func(self, *args)
|
||||
try:
|
||||
return func(self, *args)
|
||||
except Exception:
|
||||
try:
|
||||
raise ComponentError(self, 'preset loader')
|
||||
except ComponentError:
|
||||
return
|
||||
return presetWrapper
|
||||
|
||||
def updateWrapper(func):
|
||||
'''
|
||||
For undoable updates triggered by the user,
|
||||
call _userUpdate() after the subclass's update() method.
|
||||
For non-user updates, call _autoUpdate()
|
||||
Calls _preUpdate before every subclass update().
|
||||
Afterwards, for non-user updates, calls _autoUpdate().
|
||||
For undoable updates triggered by the user, calls _userUpdate()
|
||||
'''
|
||||
class wrap:
|
||||
def __init__(self, comp, auto):
|
||||
|
@ -128,24 +135,57 @@ class ComponentMetaclass(type(QtCore.QObject)):
|
|||
self.auto = auto
|
||||
|
||||
def __enter__(self):
|
||||
pass
|
||||
self.comp._preUpdate()
|
||||
|
||||
def __exit__(self, *args):
|
||||
if self.auto or self.comp.openingPreset \
|
||||
or not hasattr(self.comp.parent, 'undoStack'):
|
||||
log.verbose('Automatic update')
|
||||
self.comp._autoUpdate()
|
||||
else:
|
||||
log.verbose('User update')
|
||||
self.comp._userUpdate()
|
||||
|
||||
def updateWrapper(self, **kwargs):
|
||||
auto = False
|
||||
if 'auto' in kwargs:
|
||||
auto = kwargs['auto']
|
||||
|
||||
auto = kwargs['auto'] if 'auto' in kwargs else False
|
||||
with wrap(self, auto):
|
||||
return func(self)
|
||||
try:
|
||||
return func(self)
|
||||
except Exception:
|
||||
try:
|
||||
raise ComponentError(self, 'update method')
|
||||
except ComponentError:
|
||||
return
|
||||
return updateWrapper
|
||||
|
||||
def widgetWrapper(func):
|
||||
'''Connects all widgets to update method after the subclass's method'''
|
||||
class wrap:
|
||||
def __init__(self, comp):
|
||||
self.comp = comp
|
||||
|
||||
def __enter__(self):
|
||||
pass
|
||||
|
||||
def __exit__(self, *args):
|
||||
for widgetList in self.comp._allWidgets.values():
|
||||
for widget in widgetList:
|
||||
log.verbose('Connecting %s' % str(
|
||||
widget.__class__.__name__))
|
||||
connectWidget(widget, self.comp.update)
|
||||
|
||||
def widgetWrapper(self, *args, **kwargs):
|
||||
auto = kwargs['auto'] if 'auto' in kwargs else False
|
||||
with wrap(self):
|
||||
try:
|
||||
return func(self, *args, **kwargs)
|
||||
except Exception:
|
||||
try:
|
||||
raise ComponentError(self, 'widget creation')
|
||||
except ComponentError:
|
||||
return
|
||||
return widgetWrapper
|
||||
|
||||
def __new__(cls, name, parents, attrs):
|
||||
if 'ui' not in attrs:
|
||||
# Use module name as ui filename by default
|
||||
|
@ -153,13 +193,12 @@ class ComponentMetaclass(type(QtCore.QObject)):
|
|||
attrs['__module__'].split('.')[-1]
|
||||
)[0]
|
||||
|
||||
# if parents[0] == QtCore.QObject: else:
|
||||
decorate = (
|
||||
'names', # Class methods
|
||||
'error', 'audio', 'properties', # Properties
|
||||
'preFrameRender', 'previewRender',
|
||||
'frameRender', 'command',
|
||||
'loadPreset', 'update'
|
||||
'loadPreset', 'update', 'widget',
|
||||
)
|
||||
|
||||
# Auto-decorate methods
|
||||
|
@ -184,6 +223,8 @@ class ComponentMetaclass(type(QtCore.QObject)):
|
|||
attrs[key] = cls.loadPresetWrapper(attrs[key])
|
||||
elif key == 'update':
|
||||
attrs[key] = cls.updateWrapper(attrs[key])
|
||||
elif key == 'widget' and parents[0] != QtCore.QObject:
|
||||
attrs[key] = cls.widgetWrapper(attrs[key])
|
||||
|
||||
# Turn version string into a number
|
||||
try:
|
||||
|
@ -224,23 +265,28 @@ class Component(QtCore.QObject, metaclass=ComponentMetaclass):
|
|||
self.moduleIndex = moduleIndex
|
||||
self.compPos = compPos
|
||||
self.core = core
|
||||
self.currentPreset = None
|
||||
self.openingPreset = False
|
||||
|
||||
# STATUS VARIABLES
|
||||
self.currentPreset = None
|
||||
self._allWidgets = {}
|
||||
self._trackedWidgets = {}
|
||||
self._presetNames = {}
|
||||
self._commandArgs = {}
|
||||
self._colorWidgets = {}
|
||||
self._colorFuncs = {}
|
||||
self._relativeWidgets = {}
|
||||
# pixel values stored as floats
|
||||
# Pixel values stored as floats
|
||||
self._relativeValues = {}
|
||||
# maximum values of spinBoxes at 1080p (Core.resolutions[0])
|
||||
# Maximum values of spinBoxes at 1080p (Core.resolutions[0])
|
||||
self._relativeMaximums = {}
|
||||
|
||||
# LOCKING VARIABLES
|
||||
self.openingPreset = False
|
||||
self._lockedProperties = None
|
||||
self._lockedError = None
|
||||
self._lockedSize = None
|
||||
# If set to a dict, values are used as basis to update relative widgets
|
||||
self.oldAttrs = None
|
||||
|
||||
# Stop lengthy processes in response to this variable
|
||||
self.canceled = False
|
||||
|
@ -338,21 +384,21 @@ class Component(QtCore.QObject, metaclass=ComponentMetaclass):
|
|||
'''
|
||||
self.parent = parent
|
||||
self.settings = parent.settings
|
||||
log.verbose('Creating UI for %s #%s\'s widget' % (
|
||||
self.name, self.compPos
|
||||
))
|
||||
self.page = self.loadUi(self.__class__.ui)
|
||||
|
||||
# Connect widget signals
|
||||
widgets = {
|
||||
# Find all normal widgets which will be connected after subclass method
|
||||
self._allWidgets = {
|
||||
'lineEdit': self.page.findChildren(QtWidgets.QLineEdit),
|
||||
'checkBox': self.page.findChildren(QtWidgets.QCheckBox),
|
||||
'spinBox': self.page.findChildren(QtWidgets.QSpinBox),
|
||||
'comboBox': self.page.findChildren(QtWidgets.QComboBox),
|
||||
}
|
||||
widgets['spinBox'].extend(
|
||||
self._allWidgets['spinBox'].extend(
|
||||
self.page.findChildren(QtWidgets.QDoubleSpinBox)
|
||||
)
|
||||
for widgetList in widgets.values():
|
||||
for widget in widgetList:
|
||||
connectWidget(widget, self.update)
|
||||
|
||||
def update(self):
|
||||
'''
|
||||
|
@ -427,10 +473,15 @@ class Component(QtCore.QObject, metaclass=ComponentMetaclass):
|
|||
# =~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~==~=~=~=~=~=~=~=~=~=~=~=~=~=~
|
||||
# "Private" Methods
|
||||
# =~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~==~=~=~=~=~=~=~=~=~=~=~=~=~=~
|
||||
def _preUpdate(self):
|
||||
'''Happens before subclass update()'''
|
||||
for attr in self._relativeWidgets:
|
||||
self.updateRelativeWidget(attr)
|
||||
|
||||
def _userUpdate(self):
|
||||
'''An undoable component update triggered by the user'''
|
||||
'''Happens after subclass update() for an undoable update by user.'''
|
||||
oldWidgetVals = {
|
||||
attr: getattr(self, attr)
|
||||
attr: copy(getattr(self, attr))
|
||||
for attr in self._trackedWidgets
|
||||
}
|
||||
newWidgetVals = {
|
||||
|
@ -443,13 +494,12 @@ class Component(QtCore.QObject, metaclass=ComponentMetaclass):
|
|||
for attr, val in newWidgetVals.items()
|
||||
if val != oldWidgetVals[attr]
|
||||
}
|
||||
|
||||
if modifiedWidgets:
|
||||
action = ComponentUpdate(self, oldWidgetVals, modifiedWidgets)
|
||||
self.parent.undoStack.push(action)
|
||||
|
||||
def _autoUpdate(self):
|
||||
'''An internal component update that is not undoable'''
|
||||
'''Happens after subclass update() for an internal component update.'''
|
||||
newWidgetVals = {
|
||||
attr: getWidgetValue(widget)
|
||||
for attr, widget in self._trackedWidgets.items()
|
||||
|
@ -459,12 +509,12 @@ class Component(QtCore.QObject, metaclass=ComponentMetaclass):
|
|||
|
||||
def setAttrs(self, attrDict):
|
||||
'''
|
||||
Sets attrs (linked to trackedWidgets) in this preset to
|
||||
Sets attrs (linked to trackedWidgets) in this component to
|
||||
the values in the attrDict. Mutates certain widget values if needed
|
||||
'''
|
||||
for attr, val in attrDict.items():
|
||||
if attr in self._colorWidgets:
|
||||
# Color Widgets: text stored as tuple & update the button color
|
||||
# Color Widgets must have a tuple & have a button to update
|
||||
if type(val) is tuple:
|
||||
rgbTuple = val
|
||||
else:
|
||||
|
@ -475,15 +525,25 @@ class Component(QtCore.QObject, metaclass=ComponentMetaclass):
|
|||
self._colorWidgets[attr].setStyleSheet(btnStyle)
|
||||
setattr(self, attr, rgbTuple)
|
||||
|
||||
elif attr in self._relativeWidgets:
|
||||
# Relative widgets: number scales to fit export resolution
|
||||
self.updateRelativeWidget(attr)
|
||||
setattr(self, attr, val)
|
||||
|
||||
else:
|
||||
# Normal tracked widget
|
||||
setattr(self, attr, val)
|
||||
|
||||
def setWidgetValues(self, attrDict):
|
||||
'''
|
||||
Sets widgets defined by keys in trackedWidgets in this preset to
|
||||
the values in the attrDict.
|
||||
'''
|
||||
affectedWidgets = [
|
||||
self._trackedWidgets[attr] for attr in attrDict
|
||||
]
|
||||
with blockSignals(affectedWidgets):
|
||||
for attr, val in attrDict.items():
|
||||
widget = self._trackedWidgets[attr]
|
||||
if attr in self._colorWidgets:
|
||||
val = '%s,%s,%s' % val
|
||||
setWidgetValue(widget, val)
|
||||
|
||||
def _sendUpdateSignal(self):
|
||||
if not self.core.openingProject:
|
||||
self.parent.drawPreview()
|
||||
|
@ -499,6 +559,8 @@ class Component(QtCore.QObject, metaclass=ComponentMetaclass):
|
|||
Optional args:
|
||||
'presetNames': preset variable names to replace attr names
|
||||
'commandArgs': arg keywords that differ from attr names
|
||||
'colorWidgets': identify attr as RGB tuple & update button CSS
|
||||
'relativeWidgets': change value proportionally to resolution
|
||||
|
||||
NOTE: Any kwarg key set to None will selectively disable tracking.
|
||||
'''
|
||||
|
@ -542,6 +604,8 @@ class Component(QtCore.QObject, metaclass=ComponentMetaclass):
|
|||
self._relativeMaximums[attr] = \
|
||||
self._trackedWidgets[attr].maximum()
|
||||
self.updateRelativeWidgetMaximum(attr)
|
||||
self._preUpdate()
|
||||
self._autoUpdate()
|
||||
|
||||
def pickColor(self, textWidget, button):
|
||||
'''Use color picker to get color input from the user.'''
|
||||
|
@ -627,12 +691,28 @@ class Component(QtCore.QObject, metaclass=ComponentMetaclass):
|
|||
def setRelativeWidget(self, attr, floatVal):
|
||||
'''Set a relative widget using a float'''
|
||||
pixelVal = self.pixelValForAttr(attr, floatVal)
|
||||
self._trackedWidgets[attr].setValue(pixelVal)
|
||||
with blockSignals(self._allWidgets):
|
||||
self._trackedWidgets[attr].setValue(pixelVal)
|
||||
self.update(auto=True)
|
||||
|
||||
def getOldAttr(self, attr):
|
||||
'''
|
||||
Returns previous state of this attr. Used to determine whether
|
||||
a relative widget must be updated. Required because undoing/redoing
|
||||
can make determining the 'previous' value tricky.
|
||||
'''
|
||||
if self.oldAttrs is not None:
|
||||
log.verbose('Using nonstandard oldAttr for %s' % attr)
|
||||
return self.oldAttrs[attr]
|
||||
else:
|
||||
return getattr(self, attr)
|
||||
|
||||
def updateRelativeWidget(self, attr):
|
||||
'''Called by _preUpdate() for each relativeWidget before each update'''
|
||||
try:
|
||||
oldUserValue = getattr(self, attr)
|
||||
except AttributeError:
|
||||
oldUserValue = self.getOldAttr(attr)
|
||||
except (AttributeError, KeyError):
|
||||
log.info('Using visible values as basis for relative widgets')
|
||||
oldUserValue = self._trackedWidgets[attr].value()
|
||||
newUserValue = self._trackedWidgets[attr].value()
|
||||
newRelativeVal = self.floatValForAttr(attr, newUserValue)
|
||||
|
@ -645,11 +725,10 @@ class Component(QtCore.QObject, metaclass=ComponentMetaclass):
|
|||
# means the pixel value needs to be updated
|
||||
log.debug('Updating %s #%s\'s relative widget: %s' % (
|
||||
self.name, self.compPos, attr))
|
||||
self._trackedWidgets[attr].blockSignals(True)
|
||||
self.updateRelativeWidgetMaximum(attr)
|
||||
pixelVal = self.pixelValForAttr(attr, oldRelativeVal)
|
||||
self._trackedWidgets[attr].setValue(pixelVal)
|
||||
self._trackedWidgets[attr].blockSignals(False)
|
||||
with blockSignals(self._trackedWidgets[attr]):
|
||||
self.updateRelativeWidgetMaximum(attr)
|
||||
pixelVal = self.pixelValForAttr(attr, oldRelativeVal)
|
||||
self._trackedWidgets[attr].setValue(pixelVal)
|
||||
|
||||
if attr not in self._relativeValues \
|
||||
or oldUserValue != newUserValue:
|
||||
|
@ -725,14 +804,22 @@ class ComponentUpdate(QtWidgets.QUndoCommand):
|
|||
parent.name, parent.compPos
|
||||
)
|
||||
)
|
||||
self.undone = False
|
||||
self.parent = parent
|
||||
self.oldWidgetVals = {
|
||||
attr: val
|
||||
attr: copy(val)
|
||||
for attr, val in oldWidgetVals.items()
|
||||
if attr in modifiedVals
|
||||
}
|
||||
self.modifiedVals = modifiedVals
|
||||
|
||||
# Because relative widgets change themselves every update based on
|
||||
# their previous value, we must store ALL their values in case of undo
|
||||
self.redoRelativeWidgetVals = {
|
||||
attr: copy(getattr(self.parent, attr))
|
||||
for attr in self.parent._relativeWidgets
|
||||
}
|
||||
|
||||
# Determine if this update is mergeable
|
||||
self.id_ = -1
|
||||
if len(self.modifiedVals) == 1:
|
||||
|
@ -755,15 +842,26 @@ class ComponentUpdate(QtWidgets.QUndoCommand):
|
|||
return True
|
||||
|
||||
def redo(self):
|
||||
if self.undone:
|
||||
log.debug('Redoing component update')
|
||||
self.parent.setWidgetValues(self.modifiedVals)
|
||||
self.parent.setAttrs(self.modifiedVals)
|
||||
self.parent._sendUpdateSignal()
|
||||
if self.undone:
|
||||
self.parent.oldAttrs = self.redoRelativeWidgetVals
|
||||
self.parent.update(auto=True)
|
||||
self.parent.oldAttrs = None
|
||||
else:
|
||||
self.undoRelativeWidgetVals = {
|
||||
attr: copy(getattr(self.parent, attr))
|
||||
for attr in self.parent._relativeWidgets
|
||||
}
|
||||
self.parent._sendUpdateSignal()
|
||||
|
||||
def undo(self):
|
||||
log.debug('Undoing component update')
|
||||
self.undone = True
|
||||
self.parent.oldAttrs = self.undoRelativeWidgetVals
|
||||
self.parent.setWidgetValues(self.oldWidgetVals)
|
||||
self.parent.setAttrs(self.oldWidgetVals)
|
||||
with blockSignals(self.parent):
|
||||
for attr, val in self.oldWidgetVals.items():
|
||||
widget = self.parent._trackedWidgets[attr]
|
||||
if attr in self.parent._colorWidgets:
|
||||
val = '%s,%s,%s' % val
|
||||
setWidgetValue(widget, val)
|
||||
self.parent._sendUpdateSignal()
|
||||
self.parent.update(auto=True)
|
||||
self.parent.oldAttrs = None
|
||||
|
|
|
@ -82,8 +82,6 @@ class Component(Component):
|
|||
self.page.pushButton_color2.setEnabled(False)
|
||||
self.page.fillWidget.setCurrentIndex(fillType)
|
||||
|
||||
super().update()
|
||||
|
||||
def previewRender(self):
|
||||
return self.drawFrame(self.width, self.height)
|
||||
|
||||
|
|
|
@ -84,7 +84,6 @@ class Component(Component):
|
|||
if filename:
|
||||
self.settings.setValue("componentDir", os.path.dirname(filename))
|
||||
self.page.lineEdit_image.setText(filename)
|
||||
self.update()
|
||||
|
||||
def command(self, arg):
|
||||
if '=' in arg:
|
||||
|
@ -123,4 +122,3 @@ class Component(Component):
|
|||
else:
|
||||
scaleBox.setVisible(True)
|
||||
stretchScaleBox.setVisible(False)
|
||||
super().update()
|
||||
|
|
|
@ -53,7 +53,6 @@ class Component(Component):
|
|||
if filename:
|
||||
self.settings.setValue("componentDir", os.path.dirname(filename))
|
||||
self.page.lineEdit_image.setText(filename)
|
||||
self.update()
|
||||
|
||||
def shiftGrid(self, d):
|
||||
def newGrid(Xchange, Ychange):
|
||||
|
|
|
@ -53,7 +53,6 @@ class Component(Component):
|
|||
if filename:
|
||||
self.settings.setValue("componentDir", os.path.dirname(filename))
|
||||
self.page.lineEdit_sound.setText(filename)
|
||||
self.update()
|
||||
|
||||
def commandHelp(self):
|
||||
print('Path to audio file:\n path=/filepath/to/sound.ogg')
|
||||
|
|
|
@ -76,8 +76,6 @@ class Component(Component):
|
|||
else:
|
||||
self.page.checkBox_mono.setEnabled(True)
|
||||
|
||||
super().update()
|
||||
|
||||
def previewRender(self):
|
||||
changedSize = self.updateChunksize()
|
||||
if not changedSize \
|
||||
|
@ -138,7 +136,7 @@ class Component(Component):
|
|||
'-r', self.settings.value("outputFrameRate"),
|
||||
'-ss', "{0:.3f}".format(startPt),
|
||||
'-i',
|
||||
os.path.join(self.core.wd, 'background.png')
|
||||
self.core.junkStream
|
||||
if genericPreview else inputFile,
|
||||
'-f', 'image2pipe',
|
||||
'-pix_fmt', 'rgba',
|
||||
|
|
|
@ -68,7 +68,6 @@ class Component(Component):
|
|||
self.page.spinBox_shadY.setHidden(True)
|
||||
self.page.label_shadBlur.setHidden(True)
|
||||
self.page.spinBox_shadBlur.setHidden(True)
|
||||
super().update()
|
||||
|
||||
def centerXY(self):
|
||||
self.setRelativeWidget('xPosition', 0.5)
|
||||
|
|
|
@ -52,7 +52,6 @@ class Component(Component):
|
|||
else:
|
||||
self.page.label_volume.setEnabled(False)
|
||||
self.page.spinBox_volume.setEnabled(False)
|
||||
super().update()
|
||||
|
||||
def previewRender(self):
|
||||
self.updateChunksize()
|
||||
|
@ -119,7 +118,6 @@ class Component(Component):
|
|||
if filename:
|
||||
self.settings.setValue("componentDir", os.path.dirname(filename))
|
||||
self.page.lineEdit_video.setText(filename)
|
||||
self.update()
|
||||
|
||||
def getPreviewFrame(self, width, height):
|
||||
if not self.videoPath or not os.path.exists(self.videoPath):
|
||||
|
|
|
@ -98,7 +98,7 @@ class Component(Component):
|
|||
'-r', self.settings.value("outputFrameRate"),
|
||||
'-ss', "{0:.3f}".format(startPt),
|
||||
'-i',
|
||||
os.path.join(self.core.wd, 'background.png')
|
||||
self.core.junkStream
|
||||
if genericPreview else inputFile,
|
||||
'-f', 'image2pipe',
|
||||
'-pix_fmt', 'rgba',
|
||||
|
|
11
src/core.py
11
src/core.py
|
@ -13,7 +13,7 @@ import toolkit
|
|||
|
||||
|
||||
log = logging.getLogger('AVP.Core')
|
||||
STDOUT_LOGLVL = logging.WARNING
|
||||
STDOUT_LOGLVL = logging.VERBOSE
|
||||
FILE_LOGLVL = logging.DEBUG
|
||||
|
||||
|
||||
|
@ -81,10 +81,7 @@ class Core:
|
|||
component = self.modules[moduleIndex].Component(
|
||||
moduleIndex, compPos, self
|
||||
)
|
||||
# init component's widget for loading/saving presets
|
||||
component.widget(loader)
|
||||
# use autoUpdate() method before update() this 1 time to set attrs
|
||||
component._autoUpdate()
|
||||
else:
|
||||
moduleIndex = -1
|
||||
log.debug(
|
||||
|
@ -186,9 +183,8 @@ class Core:
|
|||
if hasattr(loader, 'window'):
|
||||
for widget, value in data['WindowFields']:
|
||||
widget = eval('loader.window.%s' % widget)
|
||||
widget.blockSignals(True)
|
||||
toolkit.setWidgetValue(widget, value)
|
||||
widget.blockSignals(False)
|
||||
with toolkit.blockSignals(widget):
|
||||
toolkit.setWidgetValue(widget, value)
|
||||
|
||||
for key, value in data['Settings']:
|
||||
Core.settings.setValue(key, value)
|
||||
|
@ -474,6 +470,7 @@ class Core:
|
|||
'logDir': os.path.join(dataDir, 'log'),
|
||||
'presetDir': os.path.join(dataDir, 'presets'),
|
||||
'componentsPath': os.path.join(wd, 'components'),
|
||||
'junkStream': os.path.join(wd, 'gui', 'background.png'),
|
||||
'encoderOptions': encoderOptions,
|
||||
'resolutions': [
|
||||
'1920x1080',
|
||||
|
|
|
@ -20,11 +20,20 @@ class AddComponent(QUndoCommand):
|
|||
self.parent = parent
|
||||
self.moduleI = moduleI
|
||||
self.compI = compI
|
||||
self.comp = None
|
||||
|
||||
def redo(self):
|
||||
self.parent.core.insertComponent(self.compI, self.moduleI, self.parent)
|
||||
if self.comp is None:
|
||||
self.parent.core.insertComponent(
|
||||
self.compI, self.moduleI, self.parent)
|
||||
else:
|
||||
# inserting previously-created component
|
||||
self.parent.core.insertComponent(
|
||||
self.compI, self.comp, self.parent)
|
||||
|
||||
|
||||
def undo(self):
|
||||
self.comp = self.parent.core.selectedComponents[self.compI]
|
||||
self.parent._removeComponent(self.compI)
|
||||
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@ from toolkit import (
|
|||
)
|
||||
|
||||
|
||||
log = logging.getLogger('AVP.MainWindow')
|
||||
log = logging.getLogger('AVP.Gui.MainWindow')
|
||||
|
||||
|
||||
class MainWindow(QtWidgets.QMainWindow):
|
||||
|
@ -76,7 +76,7 @@ class MainWindow(QtWidgets.QMainWindow):
|
|||
# Create the preview window and its thread, queues, and timers
|
||||
log.debug('Creating preview window')
|
||||
self.previewWindow = PreviewWindow(self, os.path.join(
|
||||
Core.wd, "background.png"))
|
||||
Core.wd, 'gui', "background.png"))
|
||||
window.verticalLayout_previewWrapper.addWidget(self.previewWindow)
|
||||
|
||||
log.debug('Starting preview thread')
|
||||
|
|
|
@ -5,12 +5,16 @@
|
|||
from PyQt5 import QtCore, QtWidgets
|
||||
import string
|
||||
import os
|
||||
import logging
|
||||
|
||||
from toolkit import badName
|
||||
from core import Core
|
||||
from gui.actions import *
|
||||
|
||||
|
||||
log = logging.getLogger('AVP.Gui.PresetManager')
|
||||
|
||||
|
||||
class PresetManager(QtWidgets.QDialog):
|
||||
def __init__(self, window, parent):
|
||||
super().__init__(parent.window)
|
||||
|
|
|
@ -14,7 +14,7 @@ from toolkit.frame import Checkerboard
|
|||
from toolkit import disableWhenOpeningProject
|
||||
|
||||
|
||||
log = logging.getLogger("AVP.PreviewThread")
|
||||
log = logging.getLogger("AVP.Gui.PreviewThread")
|
||||
|
||||
|
||||
class Worker(QtCore.QObject):
|
||||
|
|
|
@ -7,7 +7,7 @@ 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')
|
||||
log = logging.getLogger('AVP.Gui.PreviewWindow')
|
||||
|
||||
def __init__(self, parent, img):
|
||||
super(PreviewWindow, self).__init__()
|
||||
|
|
|
@ -6,7 +6,7 @@ import logging
|
|||
from __init__ import wd
|
||||
|
||||
|
||||
log = logging.getLogger('AVP.Entrypoint')
|
||||
log = logging.getLogger('AVP.Main')
|
||||
|
||||
|
||||
def main():
|
||||
|
|
|
@ -6,19 +6,53 @@ import string
|
|||
import os
|
||||
import sys
|
||||
import subprocess
|
||||
import logging
|
||||
from copy import copy
|
||||
from collections import OrderedDict
|
||||
|
||||
|
||||
log = logging.getLogger('AVP.Toolkit.Common')
|
||||
|
||||
|
||||
class blockSignals:
|
||||
'''A context manager to temporarily block a Qt widget from updating'''
|
||||
def __init__(self, widget):
|
||||
self.widget = widget
|
||||
'''
|
||||
Context manager to temporarily block list of QtWidgets from updating,
|
||||
and guarantee restoring the previous state afterwards.
|
||||
'''
|
||||
def __init__(self, widgets):
|
||||
if type(widgets) is dict:
|
||||
self.widgets = concatDictVals(widgets)
|
||||
else:
|
||||
self.widgets = (
|
||||
widgets if hasattr(widgets, '__iter__')
|
||||
else [widgets]
|
||||
)
|
||||
|
||||
def __enter__(self):
|
||||
self.widget.blockSignals(True)
|
||||
log.verbose('Blocking signals for %s' % ", ".join([
|
||||
str(w.__class__.__name__) for w in self.widgets
|
||||
]))
|
||||
self.oldStates = [w.signalsBlocked() for w in self.widgets]
|
||||
for w in self.widgets:
|
||||
w.blockSignals(True)
|
||||
|
||||
def __exit__(self, *args):
|
||||
self.widget.blockSignals(False)
|
||||
log.verbose('Resetting blockSignals to %s' % sum(self.oldStates))
|
||||
for w, state in zip(self.widgets, self.oldStates):
|
||||
w.blockSignals(state)
|
||||
|
||||
|
||||
def concatDictVals(d):
|
||||
'''Concatenates all values in given dict into one list.'''
|
||||
key, value = d.popitem()
|
||||
d[key] = value
|
||||
final = copy(value)
|
||||
if type(final) is not list:
|
||||
final = [final]
|
||||
final.extend([val for val in d.values()])
|
||||
else:
|
||||
value.extend([item for val in d.values() for item in val])
|
||||
return final
|
||||
|
||||
|
||||
def badName(name):
|
||||
|
@ -119,12 +153,14 @@ def connectWidget(widget, func):
|
|||
elif type(widget) == QtWidgets.QComboBox:
|
||||
widget.currentIndexChanged.connect(func)
|
||||
else:
|
||||
log.warning('Failed to connect %s ' % str(widget.__class__.__name__))
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def setWidgetValue(widget, val):
|
||||
'''Generic setValue method for use with any typical QtWidget'''
|
||||
log.verbose('Setting %s to %s' % (str(widget.__class__.__name__), val))
|
||||
if type(widget) == QtWidgets.QLineEdit:
|
||||
widget.setText(val)
|
||||
elif type(widget) == QtWidgets.QSpinBox \
|
||||
|
@ -135,6 +171,7 @@ def setWidgetValue(widget, val):
|
|||
elif type(widget) == QtWidgets.QComboBox:
|
||||
widget.setCurrentIndex(val)
|
||||
else:
|
||||
log.warning('Failed to set %s ' % str(widget.__class__.__name__))
|
||||
return False
|
||||
return True
|
||||
|
||||
|
|
Reference in New Issue