Fix custom theme handling for Qt6
This commit is contained in:
@@ -254,11 +254,13 @@ def main(sysArgs: list | None = None) -> GuiMain | None:
|
||||
pass # Quietly ignore error
|
||||
|
||||
# Import GUI (after dependency checks), and launch
|
||||
from novelwriter.gui.theme import GuiTheme
|
||||
from novelwriter.guimain import GuiMain
|
||||
|
||||
if testMode:
|
||||
# Only used for testing where the test framework creates the app
|
||||
CONFIG.loadConfig()
|
||||
SHARED.initTheme(GuiTheme())
|
||||
return GuiMain()
|
||||
|
||||
app = QApplication([CONFIG.appName, (f"-style={qtStyle}")])
|
||||
@@ -274,6 +276,7 @@ def main(sysArgs: list | None = None) -> GuiMain | None:
|
||||
# Run Config steps that require the QApplication
|
||||
CONFIG.loadConfig()
|
||||
CONFIG.initLocalisation(app)
|
||||
SHARED.initTheme(GuiTheme())
|
||||
|
||||
# Launch main GUI
|
||||
nwGUI = GuiMain()
|
||||
|
||||
@@ -98,14 +98,14 @@ class NSwitch(QAbstractButton):
|
||||
trackBrush = palette.highlight()
|
||||
thumbBrush = palette.highlightedText()
|
||||
else:
|
||||
trackBrush = palette.dark()
|
||||
trackBrush = palette.mid()
|
||||
thumbBrush = palette.light()
|
||||
|
||||
if self.isEnabled():
|
||||
trackOpacity = 1.0
|
||||
else:
|
||||
trackOpacity = 0.6
|
||||
trackBrush = palette.shadow()
|
||||
trackBrush = palette.dark()
|
||||
thumbBrush = palette.mid()
|
||||
|
||||
painter.setBrush(trackBrush)
|
||||
@@ -114,6 +114,7 @@ class NSwitch(QAbstractButton):
|
||||
|
||||
painter.setBrush(thumbBrush)
|
||||
painter.drawEllipse(self._offset - self._rR, self._rB, self._rH, self._rH)
|
||||
painter.end()
|
||||
|
||||
return
|
||||
|
||||
|
||||
@@ -304,6 +304,20 @@ class GuiTheme:
|
||||
backCol = self._guiPalette.window().color()
|
||||
textCol = self._guiPalette.windowText().color()
|
||||
|
||||
# Calculate Based on Qt Fusion
|
||||
light = backCol.lighter(150)
|
||||
mid = backCol.darker(130)
|
||||
midLight = mid.lighter(110)
|
||||
dark = backCol.darker(150)
|
||||
shadow = dark.darker(135)
|
||||
|
||||
self._guiPalette.setColor(QPalette.ColorRole.Light, light)
|
||||
self._guiPalette.setColor(QPalette.ColorRole.Mid, mid)
|
||||
self._guiPalette.setColor(QPalette.ColorRole.Midlight, midLight)
|
||||
self._guiPalette.setColor(QPalette.ColorRole.Dark, dark)
|
||||
self._guiPalette.setColor(QPalette.ColorRole.Shadow, shadow)
|
||||
|
||||
# Calculate Help Text
|
||||
backLNess = backCol.lightnessF()
|
||||
textLNess = textCol.lightnessF()
|
||||
self.isLightTheme = backLNess > textLNess
|
||||
|
||||
@@ -56,7 +56,6 @@ from novelwriter.gui.projtree import GuiProjectView
|
||||
from novelwriter.gui.search import GuiProjectSearch
|
||||
from novelwriter.gui.sidebar import GuiSideBar
|
||||
from novelwriter.gui.statusbar import GuiMainStatus
|
||||
from novelwriter.gui.theme import GuiTheme
|
||||
from novelwriter.tools.dictionaries import GuiDictionaries
|
||||
from novelwriter.tools.manuscript import GuiManuscript
|
||||
from novelwriter.tools.noveldetails import GuiNovelDetails
|
||||
@@ -101,7 +100,7 @@ class GuiMain(QMainWindow):
|
||||
# ============
|
||||
|
||||
# Initialise UserData Instance
|
||||
SHARED.initSharedData(self, GuiTheme())
|
||||
SHARED.initSharedData(self)
|
||||
|
||||
# Prepare Main Window
|
||||
self.resize(*CONFIG.mainWinSize)
|
||||
@@ -1054,6 +1053,7 @@ class GuiMain(QMainWindow):
|
||||
# We are doing this manually instead of connecting to
|
||||
# paletteChanged since the processing order matters
|
||||
SHARED.theme.loadTheme()
|
||||
self.setPalette(QApplication.palette())
|
||||
self.docEditor.updateTheme()
|
||||
self.docViewer.updateTheme()
|
||||
self.docViewerPanel.updateTheme()
|
||||
|
||||
+15
-7
@@ -164,17 +164,24 @@ class SharedData(QObject):
|
||||
# Methods
|
||||
##
|
||||
|
||||
def initSharedData(self, gui: GuiMain, theme: GuiTheme) -> None:
|
||||
def initTheme(self, theme: GuiTheme) -> None:
|
||||
"""Initialise the GUI theme. This must be called before the GUI
|
||||
is created.
|
||||
"""
|
||||
self._theme = theme
|
||||
return
|
||||
|
||||
def initSharedData(self, gui: GuiMain) -> None:
|
||||
"""Initialise the SharedData instance. This must be called as
|
||||
soon as the Main GUI is created to ensure the SHARED singleton
|
||||
has the properties needed for operation.
|
||||
"""
|
||||
self._clock.start()
|
||||
self._gui = gui
|
||||
self._theme = theme
|
||||
self._resetProject()
|
||||
logger.debug("Ready: SharedData")
|
||||
logger.debug("Thread Pool Max Count: %d", QThreadPool.globalInstance().maxThreadCount())
|
||||
if pool := QThreadPool.globalInstance():
|
||||
logger.debug("Thread Pool Max Count: %d", pool.maxThreadCount())
|
||||
return
|
||||
|
||||
def closeDocument(self, tHandle: str | None = None) -> None:
|
||||
@@ -266,7 +273,8 @@ class SharedData(QObject):
|
||||
|
||||
def runInThreadPool(self, runnable: QRunnable, priority: int = 0) -> None:
|
||||
"""Queue a runnable in the application thread pool."""
|
||||
QThreadPool.globalInstance().start(runnable, priority=priority)
|
||||
if pool := QThreadPool.globalInstance():
|
||||
pool.start(runnable, priority=priority)
|
||||
return
|
||||
|
||||
def getProjectPath(
|
||||
@@ -278,13 +286,13 @@ class SharedData(QObject):
|
||||
label = (self.tr("novelWriter Project File or Zip File")
|
||||
if allowZip else self.tr("novelWriter Project File"))
|
||||
ext = f"{nwFiles.PROJ_FILE} *.zip" if allowZip else nwFiles.PROJ_FILE
|
||||
ffilter = formatFileFilter([(label, ext), "*"])
|
||||
fFilter = formatFileFilter([(label, ext), "*"])
|
||||
selected, _ = QFileDialog.getOpenFileName(
|
||||
parent, self.tr("Open Project"), str(path or ""), filter=ffilter
|
||||
parent, self.tr("Open Project"), str(path or ""), filter=fFilter
|
||||
)
|
||||
return Path(selected) if selected else None
|
||||
|
||||
def getFont(self, current: QFont, native: bool) -> tuple[QFont, bool]:
|
||||
def getFont(self, current: QFont, native: bool) -> tuple[QFont, bool | None]:
|
||||
"""Open the font dialog and select a font."""
|
||||
kwargs = {}
|
||||
if not native:
|
||||
|
||||
Reference in New Issue
Block a user