Skip to content

Commit f9292d6

Browse files
authored
Fix how document font is set (#1877)
2 parents fddd5fd + 9388ce6 commit f9292d6

File tree

4 files changed

+100
-55
lines changed

4 files changed

+100
-55
lines changed

novelwriter/gui/doceditor.py

Lines changed: 52 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,8 @@
4343
pyqtSignal, pyqtSlot
4444
)
4545
from PyQt5.QtGui import (
46-
QColor, QCursor, QFont, QKeyEvent, QKeySequence, QMouseEvent, QPalette,
47-
QPixmap, QResizeEvent, QTextBlock, QTextCursor, QTextDocument, QTextOption
46+
QColor, QCursor, QKeyEvent, QKeySequence, QMouseEvent, QPalette, QPixmap,
47+
QResizeEvent, QTextBlock, QTextCursor, QTextDocument, QTextOption
4848
)
4949
from PyQt5.QtWidgets import (
5050
QAction, QApplication, QFrame, QGridLayout, QHBoxLayout, QLabel, QLineEdit,
@@ -329,10 +329,7 @@ def initEditor(self) -> None:
329329
SHARED.updateSpellCheckLanguage()
330330

331331
# Set font
332-
font = QFont()
333-
font.setFamily(CONFIG.textFont)
334-
font.setPointSize(CONFIG.textSize)
335-
self._qDocument.setDefaultFont(font)
332+
self.initFont()
336333

337334
# Update highlighter settings
338335
self._qDocument.syntaxHighlighter.initHighlighter()
@@ -382,6 +379,23 @@ def initEditor(self) -> None:
382379

383380
return
384381

382+
def initFont(self) -> None:
383+
"""Set the font of the main widget and sub-widgets. This needs
384+
special attention since there appears to be a bug in Qt 5.15.3.
385+
See issues #1862 and #1875.
386+
"""
387+
font = self.font()
388+
font.setFamily(CONFIG.textFont)
389+
font.setPointSize(CONFIG.textSize)
390+
self.setFont(font)
391+
392+
# Reset sub-widget font to GUI font
393+
self.docHeader.updateFont()
394+
self.docFooter.updateFont()
395+
self.docSearch.updateFont()
396+
397+
return
398+
385399
def loadText(self, tHandle: str, tLine: int | None = None) -> bool:
386400
"""Load text from a document into the editor. If we have an I/O
387401
error, we must handle this and clear the editor so that we don't
@@ -2396,9 +2410,6 @@ def __init__(self, docEditor: GuiDocEditor) -> None:
23962410
iSz = SHARED.theme.baseIconSize
23972411
mPx = CONFIG.pxInt(6)
23982412

2399-
self.boxFont = SHARED.theme.guiFont
2400-
self.boxFont.setPointSizeF(0.9*SHARED.theme.fontPointSize)
2401-
24022413
self.setContentsMargins(0, 0, 0, 0)
24032414
self.setAutoFillBackground(True)
24042415
self.setFrameStyle(QFrame.Shape.StyledPanel | QFrame.Shadow.Plain)
@@ -2410,12 +2421,10 @@ def __init__(self, docEditor: GuiDocEditor) -> None:
24102421
# ==========
24112422

24122423
self.searchBox = QLineEdit(self)
2413-
self.searchBox.setFont(self.boxFont)
24142424
self.searchBox.setPlaceholderText(self.tr("Search for"))
24152425
self.searchBox.returnPressed.connect(self._doSearch)
24162426

24172427
self.replaceBox = QLineEdit(self)
2418-
self.replaceBox.setFont(self.boxFont)
24192428
self.replaceBox.setPlaceholderText(self.tr("Replace with"))
24202429
self.replaceBox.returnPressed.connect(self._doReplace)
24212430

@@ -2425,12 +2434,9 @@ def __init__(self, docEditor: GuiDocEditor) -> None:
24252434
self.searchOpt.setContentsMargins(0, 0, 0, 0)
24262435

24272436
self.searchLabel = QLabel(self.tr("Search"), self)
2428-
self.searchLabel.setFont(self.boxFont)
24292437
self.searchLabel.setIndent(CONFIG.pxInt(6))
24302438

24312439
self.resultLabel = QLabel("?/?", self)
2432-
self.resultLabel.setFont(self.boxFont)
2433-
self.resultLabel.setMinimumWidth(SHARED.theme.getTextWidth("?/?", self.boxFont))
24342440

24352441
self.toggleCase = QAction(self.tr("Case Sensitive"), self)
24362442
self.toggleCase.setCheckable(True)
@@ -2515,6 +2521,7 @@ def __init__(self, docEditor: GuiDocEditor) -> None:
25152521
self.replaceButton.setVisible(False)
25162522
self.adjustSize()
25172523

2524+
self.updateFont()
25182525
self.updateTheme()
25192526

25202527
logger.debug("Ready: GuiDocEditSearch")
@@ -2598,7 +2605,9 @@ def setResultCount(self, currRes: int | None, resCount: int | None) -> None:
25982605
numCount = f"{lim:n}+" if (resCount or 0) > lim else f"{resCount:n}"
25992606
sCurrRes = "?" if currRes is None else str(currRes)
26002607
sResCount = "?" if resCount is None else numCount
2601-
minWidth = SHARED.theme.getTextWidth(f"{sResCount}//{sResCount}", self.boxFont)
2608+
minWidth = SHARED.theme.getTextWidth(
2609+
f"{sResCount}//{sResCount}", SHARED.theme.guiFontSmall
2610+
)
26022611
self.resultLabel.setText(f"{sCurrRes}/{sResCount}")
26032612
self.resultLabel.setMinimumWidth(minWidth)
26042613
self.adjustSize()
@@ -2609,6 +2618,18 @@ def setResultCount(self, currRes: int | None, resCount: int | None) -> None:
26092618
# Methods
26102619
##
26112620

2621+
def updateFont(self) -> None:
2622+
"""Update the font settings."""
2623+
self.setFont(SHARED.theme.guiFont)
2624+
self.searchBox.setFont(SHARED.theme.guiFontSmall)
2625+
self.replaceBox.setFont(SHARED.theme.guiFontSmall)
2626+
self.searchLabel.setFont(SHARED.theme.guiFontSmall)
2627+
self.resultLabel.setFont(SHARED.theme.guiFontSmall)
2628+
self.resultLabel.setMinimumWidth(
2629+
SHARED.theme.getTextWidth("?/?", SHARED.theme.guiFontSmall)
2630+
)
2631+
return
2632+
26122633
def updateTheme(self) -> None:
26132634
"""Update theme elements."""
26142635
qPalette = QApplication.palette()
@@ -2793,10 +2814,6 @@ def __init__(self, docEditor: GuiDocEditor) -> None:
27932814
self.itemTitle.setAlignment(QtAlignCenterTop)
27942815
self.itemTitle.setFixedHeight(iPx)
27952816

2796-
lblFont = self.itemTitle.font()
2797-
lblFont.setPointSizeF(0.9*SHARED.theme.fontPointSize)
2798-
self.itemTitle.setFont(lblFont)
2799-
28002817
# Other Widgets
28012818
self.outlineMenu = QMenu(self)
28022819

@@ -2850,6 +2867,7 @@ def __init__(self, docEditor: GuiDocEditor) -> None:
28502867
self.setContentsMargins(0, 0, 0, 0)
28512868
self.setMinimumHeight(iPx + 2*mPx)
28522869

2870+
self.updateFont()
28532871
self.updateTheme()
28542872

28552873
logger.debug("Ready: GuiDocEditHeader")
@@ -2888,6 +2906,12 @@ def setOutline(self, data: dict[int, str]) -> None:
28882906
logger.debug("Document outline updated in %.3f ms", 1000*(time() - tStart))
28892907
return
28902908

2909+
def updateFont(self) -> None:
2910+
"""Update the font settings."""
2911+
self.setFont(SHARED.theme.guiFont)
2912+
self.itemTitle.setFont(SHARED.theme.guiFontSmall)
2913+
return
2914+
28912915
def updateTheme(self) -> None:
28922916
"""Update theme elements."""
28932917
self.tbButton.setThemeIcon("menu")
@@ -3001,9 +3025,6 @@ def __init__(self, parent: QWidget) -> None:
30013025
bSp = CONFIG.pxInt(4)
30023026
hSp = CONFIG.pxInt(6)
30033027

3004-
lblFont = self.font()
3005-
lblFont.setPointSizeF(0.9*SHARED.theme.fontPointSize)
3006-
30073028
# Cached Translations
30083029
self._trLineCount = self.tr("Line: {0} ({1})")
30093030
self._trWordCount = self.tr("Words: {0} ({1})")
@@ -3026,7 +3047,6 @@ def __init__(self, parent: QWidget) -> None:
30263047
self.statusText.setAutoFillBackground(True)
30273048
self.statusText.setFixedHeight(fPx)
30283049
self.statusText.setAlignment(QtAlignLeftTop)
3029-
self.statusText.setFont(lblFont)
30303050

30313051
# Lines
30323052
self.linesIcon = QLabel("", self)
@@ -3041,7 +3061,6 @@ def __init__(self, parent: QWidget) -> None:
30413061
self.linesText.setAutoFillBackground(True)
30423062
self.linesText.setFixedHeight(fPx)
30433063
self.linesText.setAlignment(QtAlignLeftTop)
3044-
self.linesText.setFont(lblFont)
30453064

30463065
# Words
30473066
self.wordsIcon = QLabel("", self)
@@ -3056,7 +3075,6 @@ def __init__(self, parent: QWidget) -> None:
30563075
self.wordsText.setAutoFillBackground(True)
30573076
self.wordsText.setFixedHeight(fPx)
30583077
self.wordsText.setAlignment(QtAlignLeftTop)
3059-
self.wordsText.setFont(lblFont)
30603078

30613079
# Assemble Layout
30623080
self.outerBox = QHBoxLayout()
@@ -3079,6 +3097,7 @@ def __init__(self, parent: QWidget) -> None:
30793097
self.setMinimumHeight(fPx + 2*mPx)
30803098

30813099
# Fix the Colours
3100+
self.updateFont()
30823101
self.updateTheme()
30833102

30843103
# Initialise Info
@@ -3092,6 +3111,14 @@ def __init__(self, parent: QWidget) -> None:
30923111
# Methods
30933112
##
30943113

3114+
def updateFont(self) -> None:
3115+
"""Update the font settings."""
3116+
self.setFont(SHARED.theme.guiFont)
3117+
self.statusText.setFont(SHARED.theme.guiFontSmall)
3118+
self.linesText.setFont(SHARED.theme.guiFontSmall)
3119+
self.wordsText.setFont(SHARED.theme.guiFontSmall)
3120+
return
3121+
30953122
def updateTheme(self) -> None:
30963123
"""Update theme elements."""
30973124
iPx = round(0.9*SHARED.theme.baseIconHeight)

novelwriter/gui/docviewer.py

Lines changed: 33 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,7 @@
3131
from enum import Enum
3232

3333
from PyQt5.QtCore import QPoint, Qt, QUrl, pyqtSignal, pyqtSlot
34-
from PyQt5.QtGui import (
35-
QCursor, QFont, QMouseEvent, QPalette, QResizeEvent, QTextCursor,
36-
QTextOption
37-
)
34+
from PyQt5.QtGui import QCursor, QMouseEvent, QPalette, QResizeEvent, QTextCursor, QTextOption
3835
from PyQt5.QtWidgets import (
3936
QAction, QApplication, QFrame, QHBoxLayout, QLabel, QMenu, QTextBrowser,
4037
QToolButton, QWidget
@@ -141,12 +138,7 @@ def updateTheme(self) -> None:
141138
def initViewer(self) -> None:
142139
"""Set editor settings from main config."""
143140
self._makeStyleSheet()
144-
145-
# Set Font
146-
font = QFont()
147-
font.setFamily(CONFIG.textFont)
148-
font.setPointSize(CONFIG.textSize)
149-
self.document().setDefaultFont(font)
141+
self.initFont()
150142

151143
# Set the widget colours to match syntax theme
152144
mainPalette = self.palette()
@@ -189,6 +181,22 @@ def initViewer(self) -> None:
189181

190182
return
191183

184+
def initFont(self) -> None:
185+
"""Set the font of the main widget and sub-widgets. This needs
186+
special attention since there appears to be a bug in Qt 5.15.3.
187+
See issues #1862 and #1875.
188+
"""
189+
font = self.font()
190+
font.setFamily(CONFIG.textFont)
191+
font.setPointSize(CONFIG.textSize)
192+
self.setFont(font)
193+
194+
# Reset sub-widget font to GUI font
195+
self.docHeader.updateFont()
196+
self.docFooter.updateFont()
197+
198+
return
199+
192200
def loadText(self, tHandle: str, updateHistory: bool = True) -> bool:
193201
"""Load text into the viewer from an item handle."""
194202
if not SHARED.project.tree.checkType(tHandle, nwItemType.FILE):
@@ -646,10 +654,6 @@ def __init__(self, docViewer: GuiDocViewer) -> None:
646654
self.itemTitle.setAlignment(QtAlignCenterTop)
647655
self.itemTitle.setFixedHeight(iPx)
648656

649-
lblFont = self.itemTitle.font()
650-
lblFont.setPointSizeF(0.9*SHARED.theme.fontPointSize)
651-
self.itemTitle.setFont(lblFont)
652-
653657
# Other Widgets
654658
self.outlineMenu = QMenu(self)
655659

@@ -700,7 +704,7 @@ def __init__(self, docViewer: GuiDocViewer) -> None:
700704
self.outerBox.setContentsMargins(mPx, mPx, mPx, mPx)
701705
self.setMinimumHeight(iPx + 2*mPx)
702706

703-
# Fix the Colours
707+
self.updateFont()
704708
self.updateTheme()
705709

706710
logger.debug("Ready: GuiDocViewHeader")
@@ -745,6 +749,12 @@ def setOutline(self, data: dict[str, tuple[str, int]]) -> None:
745749
self._docOutline = data
746750
return
747751

752+
def updateFont(self) -> None:
753+
"""Update the font settings."""
754+
self.setFont(SHARED.theme.guiFont)
755+
self.itemTitle.setFont(SHARED.theme.guiFontSmall)
756+
return
757+
748758
def updateTheme(self) -> None:
749759
"""Update theme elements."""
750760
self.outlineButton.setThemeIcon("list")
@@ -886,11 +896,6 @@ def __init__(self, docViewer: GuiDocViewer) -> None:
886896
self.showSynopsis.toggled.connect(self._doToggleSynopsis)
887897
self.showSynopsis.setToolTip(self.tr("Show Synopsis Comments"))
888898

889-
lblFont = self.font()
890-
lblFont.setPointSizeF(0.9*SHARED.theme.fontPointSize)
891-
self.showComments.setFont(lblFont)
892-
self.showSynopsis.setFont(lblFont)
893-
894899
# Assemble Layout
895900
self.outerBox = QHBoxLayout()
896901
self.outerBox.addWidget(self.showHide, 0)
@@ -906,7 +911,7 @@ def __init__(self, docViewer: GuiDocViewer) -> None:
906911
self.outerBox.setContentsMargins(mPx, mPx, mPx, mPx)
907912
self.setMinimumHeight(iPx + 2*mPx)
908913

909-
# Fix the Colours
914+
self.updateFont()
910915
self.updateTheme()
911916

912917
logger.debug("Ready: GuiDocViewFooter")
@@ -917,6 +922,13 @@ def __init__(self, docViewer: GuiDocViewer) -> None:
917922
# Methods
918923
##
919924

925+
def updateFont(self) -> None:
926+
"""Update the font settings."""
927+
self.setFont(SHARED.theme.guiFont)
928+
self.showComments.setFont(SHARED.theme.guiFontSmall)
929+
self.showSynopsis.setFont(SHARED.theme.guiFontSmall)
930+
return
931+
920932
def updateTheme(self) -> None:
921933
"""Update theme elements."""
922934
# Icons

novelwriter/gui/theme.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,7 @@
3030
from pathlib import Path
3131

3232
from PyQt5.QtCore import QSize, Qt
33-
from PyQt5.QtGui import (
34-
QPalette, QColor, QIcon, QFont, QFontMetrics, QFontDatabase, QPixmap
35-
)
33+
from PyQt5.QtGui import QColor, QFont, QFontDatabase, QFontMetrics, QIcon, QPalette, QPixmap
3634
from PyQt5.QtWidgets import QApplication
3735

3836
from novelwriter import CONFIG
@@ -154,6 +152,8 @@ def __init__(self) -> None:
154152
self.guiFont = QApplication.font()
155153
self.guiFontB = QApplication.font()
156154
self.guiFontB.setBold(True)
155+
self.guiFontSmall = QApplication.font()
156+
self.guiFontSmall.setPointSizeF(0.9*self.guiFont.pointSizeF())
157157

158158
qMetric = QFontMetrics(self.guiFont)
159159
fHeight = qMetric.height()

novelwriter/tools/manuscript.py

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
from typing import TYPE_CHECKING
3232

3333
from PyQt5.QtCore import Qt, QTimer, QUrl, pyqtSignal, pyqtSlot
34-
from PyQt5.QtGui import QCloseEvent, QColor, QCursor, QFont, QPalette, QResizeEvent
34+
from PyQt5.QtGui import QCloseEvent, QColor, QCursor, QPalette, QResizeEvent
3535
from PyQt5.QtPrintSupport import QPrinter, QPrintPreviewDialog
3636
from PyQt5.QtWidgets import (
3737
QAbstractItemView, QApplication, QDialog, QFormLayout, QGridLayout,
@@ -761,7 +761,6 @@ def __init__(self, parent: QWidget) -> None:
761761
self.setPalette(dPalette)
762762

763763
self.setMinimumWidth(40*SHARED.theme.textNWidth)
764-
self.setTextFont(CONFIG.textFont, CONFIG.textSize)
765764
self.setTabStopDistance(CONFIG.getTabWidth())
766765
self.setOpenExternalLinks(False)
767766

@@ -802,6 +801,8 @@ def __init__(self, parent: QWidget) -> None:
802801
self._updateDocMargins()
803802
self._updateBuildAge()
804803

804+
self.setTextFont(CONFIG.textFont, CONFIG.textSize)
805+
805806
# Age Timer
806807
self.ageTimer = QTimer(self)
807808
self.ageTimer.setInterval(10000)
@@ -831,12 +832,17 @@ def setJustify(self, state: bool) -> None:
831832
return
832833

833834
def setTextFont(self, family: str, size: int) -> None:
834-
"""Set the text font properties."""
835-
if family:
836-
font = QFont()
835+
"""Set the text font properties and then reset for sub-widgets.
836+
This needs special attention since there appears to be a bug in
837+
Qt 5.15.3. See issues #1862 and #1875.
838+
"""
839+
if family and size > 4:
840+
font = self.font()
837841
font.setFamily(family)
838842
font.setPointSize(size)
839-
self.document().setDefaultFont(font)
843+
self.setFont(font)
844+
self.buildProgress.setFont(SHARED.theme.guiFont)
845+
self.ageLabel.setFont(SHARED.theme.guiFontSmall)
840846
return
841847

842848
##

0 commit comments

Comments
 (0)