diff --git a/novelwriter/extensions/modified.py b/novelwriter/extensions/modified.py index 4eb50cff..8c49e6dd 100644 --- a/novelwriter/extensions/modified.py +++ b/novelwriter/extensions/modified.py @@ -27,11 +27,23 @@ from __future__ import annotations from PyQt5.QtCore import QSize, Qt from PyQt5.QtGui import QWheelEvent -from PyQt5.QtWidgets import QComboBox, QDoubleSpinBox, QSpinBox, QToolButton, QWidget +from PyQt5.QtWidgets import QComboBox, QDialog, QDoubleSpinBox, QSpinBox, QToolButton, QWidget from novelwriter import SHARED +class NDialog(QDialog): + + def softDelete(self) -> None: + """Since calling deleteLater is sometimes not safe from Python, + as the C++ object can be deleted before the Python process is + done with the object, we instead set the dialog's parent to None + so that it gets garbage collected when it runs out of scope. + """ + self.setParent(None) # type: ignore + return + + class NComboBox(QComboBox): def __init__(self, parent: QWidget | None = None) -> None: diff --git a/novelwriter/tools/manuscript.py b/novelwriter/tools/manuscript.py index 12ca8212..0d32457d 100644 --- a/novelwriter/tools/manuscript.py +++ b/novelwriter/tools/manuscript.py @@ -34,10 +34,10 @@ from PyQt5.QtCore import Qt, QTimer, QUrl, pyqtSignal, pyqtSlot from PyQt5.QtGui import QCloseEvent, QColor, QCursor, QPalette, QResizeEvent from PyQt5.QtPrintSupport import QPrinter, QPrintPreviewDialog from PyQt5.QtWidgets import ( - QAbstractItemView, QApplication, QDialog, QFormLayout, QGridLayout, - QHBoxLayout, QLabel, QListWidget, QListWidgetItem, QPushButton, - QSizePolicy, QSplitter, QStackedWidget, QTabWidget, QTextBrowser, - QTreeWidget, QTreeWidgetItem, QVBoxLayout, QWidget + QAbstractItemView, QApplication, QFormLayout, QGridLayout, QHBoxLayout, + QLabel, QListWidget, QListWidgetItem, QPushButton, QSizePolicy, QSplitter, + QStackedWidget, QTabWidget, QTextBrowser, QTreeWidget, QTreeWidgetItem, + QVBoxLayout, QWidget ) from novelwriter import CONFIG, SHARED @@ -48,7 +48,7 @@ from novelwriter.core.tohtml import ToHtml from novelwriter.core.tokenizer import HeadingFormatter from novelwriter.error import logException from novelwriter.extensions.circularprogress import NProgressCircle -from novelwriter.extensions.modified import NIconToggleButton, NIconToolButton +from novelwriter.extensions.modified import NDialog, NIconToggleButton, NIconToolButton from novelwriter.gui.theme import STYLES_FLAT_TABS, STYLES_MIN_TOOLBUTTON from novelwriter.tools.manusbuild import GuiManuscriptBuild from novelwriter.tools.manussettings import GuiBuildSettings @@ -63,7 +63,7 @@ if TYPE_CHECKING: # pragma: no cover logger = logging.getLogger(__name__) -class GuiManuscript(QDialog): +class GuiManuscript(NDialog): """GUI Tools: Manuscript Tool The dialog displays all the users build definitions, a preview panel @@ -285,7 +285,7 @@ class GuiManuscript(QDialog): if isinstance(obj, GuiBuildSettings) and obj.isVisible(): obj.close() event.accept() - self.deleteLater() + self.softDelete() return ## diff --git a/novelwriter/tools/manussettings.py b/novelwriter/tools/manussettings.py index a27c011f..a36a7c44 100644 --- a/novelwriter/tools/manussettings.py +++ b/novelwriter/tools/manussettings.py @@ -30,8 +30,8 @@ from typing import TYPE_CHECKING from PyQt5.QtCore import QEvent, Qt, pyqtSignal, pyqtSlot from PyQt5.QtGui import QFont, QIcon, QSyntaxHighlighter, QTextCharFormat, QTextDocument from PyQt5.QtWidgets import ( - QAbstractButton, QAbstractItemView, QDialog, QDialogButtonBox, QFontDialog, - QFrame, QGridLayout, QHBoxLayout, QHeaderView, QLabel, QLineEdit, QMenu, + QAbstractButton, QAbstractItemView, QDialogButtonBox, QFontDialog, QFrame, + QGridLayout, QHBoxLayout, QHeaderView, QLabel, QLineEdit, QMenu, QPlainTextEdit, QPushButton, QSplitter, QStackedWidget, QTreeWidget, QTreeWidgetItem, QVBoxLayout, QWidget ) @@ -42,7 +42,9 @@ from novelwriter.core.buildsettings import BuildSettings, FilterMode from novelwriter.extensions.configlayout import ( NColourLabel, NFixedPage, NScrollableForm, NScrollablePage ) -from novelwriter.extensions.modified import NComboBox, NDoubleSpinBox, NIconToolButton, NSpinBox +from novelwriter.extensions.modified import ( + NComboBox, NDialog, NDoubleSpinBox, NIconToolButton, NSpinBox +) from novelwriter.extensions.pagedsidebar import NPagedSideBar from novelwriter.extensions.switch import NSwitch from novelwriter.extensions.switchbox import NSwitchBox @@ -57,7 +59,7 @@ if TYPE_CHECKING: # pragma: no cover logger = logging.getLogger(__name__) -class GuiBuildSettings(QDialog): +class GuiBuildSettings(NDialog): """GUI Tools: Manuscript Build Settings Dialog The main tool for configuring manuscript builds. It's a GUI tool for @@ -199,7 +201,7 @@ class GuiBuildSettings(QDialog): self._askToSaveBuild() self._saveSettings() event.accept() - self.deleteLater() + self.softDelete() return ##