diff --git a/src/classes/exporters/final_cut_pro.py b/src/classes/exporters/final_cut_pro.py index c477db111a..ddaf661076 100644 --- a/src/classes/exporters/final_cut_pro.py +++ b/src/classes/exporters/final_cut_pro.py @@ -57,7 +57,7 @@ def createEffect(xmldoc, name, node, points, scale): first_value = None for keyframeTime in sorted(keyframes.keys()): keyframeValue = keyframes.get(keyframeTime) - if first_value == None: + if first_value is None: first_value = keyframeValue # Create keyframe element for each point @@ -230,4 +230,6 @@ def export_xml(): file.close() except IOError as inst: log.error("Error writing XML export: {}".format(str(inst))) - + finally: + # Free up DOM memory + xmldoc.unlink() diff --git a/src/classes/importers/final_cut_pro.py b/src/classes/importers/final_cut_pro.py index c76921c4eb..abb602d90f 100644 --- a/src/classes/importers/final_cut_pro.py +++ b/src/classes/importers/final_cut_pro.py @@ -201,3 +201,6 @@ def import_xml(): # Update the preview and reselect current frame in properties app.window.refreshFrameSignal.emit() app.window.propertyTableView.select_frame(app.window.preview_thread.player.Position()) + + # Free up DOM memory + xmldoc.unlink() diff --git a/src/windows/export.py b/src/windows/export.py index cd210b59ff..f5ef754578 100644 --- a/src/windows/export.py +++ b/src/windows/export.py @@ -31,19 +31,25 @@ import xml.dom.minidom as xml import tempfile +import openshot -from PyQt5.QtCore import * -from PyQt5.QtWidgets import * -from PyQt5.QtGui import QIcon +from PyQt5.QtCore import Qt, QCoreApplication, QTimer +from PyQt5.QtWidgets import ( + QMessageBox, QDialog, QFileDialog, QDialogButtonBox, QPushButton +) +from PyQt5.QtGui import QSize, QIcon from classes import info from classes import ui_util +from classes import settings +from classes.logger import log from classes.app import get_app -from classes.metrics import * +from classes.metrics import track_metric_screen, track_metric_error from classes.query import File import json + class Export(QDialog): """ Export Dialog """ @@ -229,9 +235,11 @@ def __init__(self): presets = [] for preset_path in [info.EXPORT_PRESETS_PATH, info.USER_PRESETS_PATH]: for file in os.listdir(preset_path): - xmldoc = xml.parse(os.path.join(preset_path, file)) - type = xmldoc.getElementsByTagName("type") - presets.append(_(type[0].childNodes[0].data)) + # Use context manager to automatically unlink xmldoc objects + with xml.parse(os.path.join(preset_path, file)) as xmldoc: + type = xmldoc.getElementsByTagName("type") + presets.append(_(type[0].childNodes[0].data)) + # Exclude duplicates type_index = 0 @@ -395,6 +403,9 @@ def cboSimpleProjectType_index_changed(self, widget, index): elif openshot.FFmpegWriter.IsValidCodec(codec_text): acceleration_types[_(title.childNodes[0].data)] = QIcon(":/hw/hw-accel-none.svg") + # Free up DOM memory + xmldoc.unlink() + # Add all targets for selected project type preset_index = 0 selected_preset = 0 @@ -539,6 +550,9 @@ def cboSimpleTarget_index_changed(self, widget, index): break layout_index += 1 + # Free up DOM memory + xmldoc.unlink() + # init the profiles combo for item in sorted(profiles_list): self.cboSimpleVideoProfile.addItem(self.getProfileName(self.getProfilePath(item)), self.getProfilePath(item)) diff --git a/src/windows/file_properties.py b/src/windows/file_properties.py index 8531c7b2d1..62408d35d6 100644 --- a/src/windows/file_properties.py +++ b/src/windows/file_properties.py @@ -26,21 +26,19 @@ """ import os -import locale -import xml.dom.minidom as xml -import functools -from PyQt5.QtCore import * -from PyQt5.QtWidgets import * +from PyQt5.QtWidgets import QDialog, QFileDialog, QDialogButtonBox, QPushButton + import openshot # Python module for libopenshot (required video editing module installed separately) from classes import info, ui_util, settings from classes.app import get_app from classes.logger import log -from classes.metrics import * +from classes.metrics import track_metric_screen import json + class FileProperties(QDialog): """ File Properties Dialog """ @@ -183,7 +181,7 @@ def accept(self): self.file.data["name"] = self.txtFileName.text() self.file.data["tags"] = self.txtTags.text() - #experimental: update file path + # experimental: update file path self.file.data["path"] = self.txtFilePath.text() # Update Framerate diff --git a/src/windows/title_editor.py b/src/windows/title_editor.py index da0cb58141..aa90b8a505 100644 --- a/src/windows/title_editor.py +++ b/src/windows/title_editor.py @@ -26,7 +26,6 @@ along with OpenShot Library. If not, see . """ -import sys import os import re import shutil @@ -35,17 +34,20 @@ import tempfile from xml.dom import minidom -from PyQt5.QtCore import * -from PyQt5.QtGui import QIcon, QStandardItemModel, QStandardItem, QFont -from PyQt5.QtWidgets import * -from PyQt5 import uic, QtSvg, QtGui +from PyQt5.QtCore import Qt, QTimer +from PyQt5 import QtGui +from PyQt5.QtWidgets import ( + QGraphicsScene, QMessageBox, QDialog, QColorDialog, QFontDialog, + QPushButton, QTextEdit, QLabel +) + import openshot -from classes import info, ui_util, settings, qt_types, updates +from classes import info, ui_util, settings from classes.logger import log from classes.app import get_app from classes.query import File -from classes.metrics import * +from classes.metrics import track_metric_screen from windows.views.titles_listview import TitlesListView import json @@ -102,7 +104,7 @@ def __init__(self, edit_file_path=None, duplicate=False): self.font_family = "Bitstream Vera Sans" self.tspan_node = None - self.qfont = QFont(self.font_family) + self.qfont = QtGui.QFont(self.font_family) # Add titles list view self.titlesTreeView = TitlesListView(self) @@ -202,7 +204,7 @@ def load_svg_template(self): self.font_family = "Bitstream Vera Sans" if self.qfont: del self.qfont - self.qfont = QFont(self.font_family) + self.qfont = QtGui.QFont(self.font_family) # Loop through child widgets (and remove them) for child in self.settingsContainer.children(): @@ -276,7 +278,6 @@ def load_svg_template(self): widget.textChanged.connect(functools.partial(self.txtLine_changed, widget)) self.settingsContainer.layout().addRow(label, widget) - # Add Font button label = QLabel() label.setText(_("Font:")) @@ -340,7 +341,7 @@ def writeToFile(self, xmldoc): file.write(bytes(xmldoc.toxml(), 'UTF-8')) file.close() except IOError as inst: - log.error("Error writing SVG title") + log.error("Error writing SVG title: {}".format(inst)) def btnFontColor_clicked(self): app = get_app() @@ -624,7 +625,6 @@ def set_font_color_elements(self, color, alpha): t = ";" text_child.setAttribute("style", t.join(ar)) - # Loop through each TSPAN for tspan_child in self.tspan_node: @@ -660,8 +660,11 @@ def accept(self): if self.txtFileName.toPlainText().strip(): # Do we have unsaved changes? if os.path.exists(file_path) and not self.edit_file_path: - ret = QMessageBox.question(self, _("Title Editor"), _("%s already exists.\nDo you want to replace it?") % file_name, - QMessageBox.No | QMessageBox.Yes) + ret = QMessageBox.question( + self, _("Title Editor"), + _("%s already exists.\nDo you want to replace it?") % file_name, + QMessageBox.No | QMessageBox.Yes + ) if ret == QMessageBox.No: # Do nothing return @@ -682,7 +685,6 @@ def add_file(self, filepath): filename = os.path.basename(filepath) # Add file into project - app = get_app() _ = get_app()._tr # Check for this path in our existing project data