From 3e6d197c78526e5f548c4d6592a41541df8a72bb Mon Sep 17 00:00:00 2001
From: Lucas Brown
Date: Fri, 2 May 2025 17:02:53 -0500
Subject: [PATCH 1/3] * Fixed fonts leaking out to host apps like Maya *
Refactored where the font db is loaded * Reliably getting fonts out of the db
by id * Fixed a bug with how the code editor number bar was dealing with
fonts Fixes #284
---
nxt_editor/constants.py | 15 ++++++++++++--
nxt_editor/dockwidgets/code_editor.py | 26 +++++++++++++-----------
nxt_editor/main_window.py | 29 +++++++++++----------------
3 files changed, 39 insertions(+), 31 deletions(-)
diff --git a/nxt_editor/constants.py b/nxt_editor/constants.py
index 66a3d48..d98d763 100644
--- a/nxt_editor/constants.py
+++ b/nxt_editor/constants.py
@@ -1,7 +1,8 @@
# Builtin
import os
import json
-
+# External
+from Qt import QtGui
# Internal
from nxt.constants import USER_DIR
@@ -22,8 +23,18 @@ class EDITOR_VERSION(object):
class FONTS(object):
- DEFAULT_FAMILY = 'Roboto Mono'
DEFAULT_SIZE = 10
+ # Load fonts once
+ _font_db = QtGui.QFontDatabase()
+ _roboto_id = _font_db.addApplicationFont(":/fonts/fonts/Roboto/Roboto-Regular.ttf")
+ _mono_id = _font_db.addApplicationFont(":/fonts/fonts/RobotoMono/RobotoMono-Regular.ttf")
+
+ # Get actual family names from font DB
+ ROBOTO_FAMILY = _font_db.applicationFontFamilies(_roboto_id)[0] if _roboto_id != -1 else "Sans Serif"
+ ROBOTO_MONO_FAMILY = _font_db.applicationFontFamilies(_mono_id)[0] if _mono_id != -1 else "Monospace"
+
+ DEFAULT_FAMILY = ROBOTO_FAMILY
+ CODE_EDITOR_FAMILY = ROBOTO_MONO_FAMILY
PREF_DIR_INT = EDITOR_VERSION.MAJOR
diff --git a/nxt_editor/dockwidgets/code_editor.py b/nxt_editor/dockwidgets/code_editor.py
index dd1b42d..d85f33c 100644
--- a/nxt_editor/dockwidgets/code_editor.py
+++ b/nxt_editor/dockwidgets/code_editor.py
@@ -16,6 +16,7 @@
from nxt import DATA_STATE, nxt_path
from nxt.nxt_node import INTERNAL_ATTRS
from nxt_editor.dockwidgets import syntax
+from nxt_editor.constants import FONTS
import nxt_editor
logger = logging.getLogger(nxt_editor.LOGGER_NAME)
@@ -72,7 +73,7 @@ def __init__(self, title='Code Editor', parent=None, minimum_width=500):
self.details_layout.addLayout(self.name_layout)
self.name_label = LabelEdit(parent=self.details_frame)
- self.name_label.setFont(QtGui.QFont("Roboto", 14))
+ self.name_label.setFont(QtGui.QFont(FONTS.DEFAULT_FAMILY, 14))
self.name_label.nameChangeRequested.connect(self.edit_name)
self.name_layout.addWidget(self.name_label, 0, QtCore.Qt.AlignLeft)
@@ -86,7 +87,7 @@ def __init__(self, title='Code Editor', parent=None, minimum_width=500):
self.name_layout.addWidget(self.name_edit_button, 0, QtCore.Qt.AlignLeft)
self.path_label = QtWidgets.QLabel(parent=self.details_frame)
- self.path_label.setFont(QtGui.QFont("Roboto Mono", 8))
+ self.path_label.setFont(QtGui.QFont(FONTS.CODE_EDITOR_FAMILY, 8))
self.path_label.setStyleSheet('color: grey')
self.details_layout.addWidget(self.path_label)
@@ -600,8 +601,8 @@ def __init__(self, show_line_numbers=True, highlight_current_line=True,
self.setFocusPolicy(QtCore.Qt.ClickFocus)
# font settings
- self.font_size = 10
- self.font_family = 'Roboto Mono'
+ self.font_family = FONTS.CODE_EDITOR_FAMILY
+ self.font_size = FONTS.DEFAULT_SIZE
self.setFont(QtGui.QFont(self.font_family, self.font_size))
self.setLineWrapMode(QtWidgets.QPlainTextEdit.NoWrap)
@@ -754,7 +755,9 @@ def set_font_size(self, delta=0.0, default=False):
self.font_size = 10
else:
self.font_size += delta
- self.setFont(QtGui.QFont(self.font_family, self.font_size))
+ font = self.font()
+ font.setPointSize(self.font_size)
+ self.setFont(font)
def update_previous_scroll_positions(self):
self.prev_v_scroll_value = self.verticalScrollBar().value()
@@ -1217,7 +1220,6 @@ def __init__(self, editor, color):
self.editor = editor
self.editor.blockCountChanged.connect(self.update_width)
self.editor.updateRequest.connect(self.update_contents)
- self.font = QtGui.QFont()
self.color = QtGui.QColor(color)
self.update_width()
@@ -1231,7 +1233,7 @@ def paintEvent(self, event):
changed_lines = []
# Iterate over all visible text blocks in the document.
while block.isValid():
- self.font.setBold(False)
+ self.font().setBold(False)
block_number = block.blockNumber()
block_top = self.editor.blockBoundingGeometry(block).translated(
self.editor.contentOffset()).top()
@@ -1241,7 +1243,7 @@ def paintEvent(self, event):
# We want the line number for the selected line to be bold.
painter.setPen(QtGui.QColor(colors.LIGHTER_TEXT))
if block_number == self.editor.textCursor().blockNumber():
- self.font.setBold(True)
+ self.font().setBold(True)
else:
painter.setPen(colors.DEFAULT_TEXT)
# Draw the line number right justified at the position of the line.
@@ -1252,7 +1254,7 @@ def paintEvent(self, event):
painter.fillRect(paint_rect, colors.UNSAVED)
painter.setPen(colors.LIGHTEST_TEXT)
changed_lines.remove(block_number)
- painter.setFont(self.font)
+ painter.setFont(self.font())
text_rect = paint_rect.marginsAdded(QtCore.QMargins(0, 0, -4, 0))
painter.drawText(text_rect, QtCore.Qt.AlignRight,
str(block_number + 1))
@@ -1288,8 +1290,8 @@ def update_contents(self, rect, scroll):
if rect.contains(self.editor.viewport().rect()):
font_size = self.editor.currentCharFormat().font().pointSize()
- self.font.setPointSize(font_size)
- self.font.setStyle(QtGui.QFont.StyleNormal)
+ self.font().setPointSize(font_size)
+ self.font().setStyle(QtGui.QFont.StyleNormal)
self.update_width()
@@ -1310,7 +1312,7 @@ def __init__(self, parent=None):
def paintEvent(self, event):
painter = QtGui.QPainter()
painter.begin(self)
- painter.setFont(QtGui.QFont("Roboto", 14))
+ painter.setFont(QtGui.QFont(FONTS.CODE_EDITOR_FAMILY, 14))
font_metrics = QtGui.QFontMetrics(painter.font())
painter.setRenderHint(QtGui.QPainter.Antialiasing)
# actual_display_state
diff --git a/nxt_editor/main_window.py b/nxt_editor/main_window.py
index a478e59..b437220 100644
--- a/nxt_editor/main_window.py
+++ b/nxt_editor/main_window.py
@@ -122,11 +122,7 @@ def __init__(self, filepath=None, parent=None, start_rpc=False):
style_file.open(QtCore.QFile.ReadOnly)
self.stylesheet = str(style_file.readAll())
self.setStyleSheet(self.stylesheet)
-
- # fonts
- font_db = QtGui.QFontDatabase()
- font_db.addApplicationFont(":fonts/fonts/RobotoMono/RobotoMono-Regular.ttf")
- font_db.addApplicationFont(":fonts/fonts/Roboto/Roboto-Regular.ttf")
+ self.setFont(QtGui.QFont(FONTS.DEFAULT_FAMILY, FONTS.DEFAULT_SIZE))
# nxt object in charge of loaded graphs
self.nxt = Session()
@@ -365,24 +361,23 @@ def decrease_font_size(self):
self._change_font_size(-1)
def _change_font_size(self, delta, absolute=False, save=True):
- app = QtWidgets.QApplication.instance()
if absolute:
font_size = delta
else:
- font_size = app.font().pointSize() + delta
+ font_size = self.font().pointSize() + delta
self.font_size_changed.emit(delta)
if save:
user_dir.user_prefs[user_dir.USER_PREF.FONT_SIZE] = font_size
- font = QtGui.QFont(FONTS.DEFAULT_FAMILY, font_size)
- app.setFont(font)
-
- widgets_with_fonts = ["QMenuBar", "QTabWidget", "QMenu", "QTableView",
- "QLineEdit", "QComboBox", "QLabel",
- "QPushButton", "QTextEdit", "QWidget",
- "QListWidget", "QTabelWidget", "QTreeWidget",
- "QSpinBox", "QDoubleSpinBox", "QCheckBox"]
- for widget in widgets_with_fonts:
- app.setFont(font, widget)
+ main_font = self.font()
+ main_font.setPointSize(font_size)
+ self.setFont(main_font)
+ self.setUpdatesEnabled(False)
+ for widget in self.findChildren(QtWidgets.QWidget):
+ update_font = widget.font()
+ update_font.setPointSize(font_size)
+ widget.setFont(update_font)
+ self.setUpdatesEnabled(True)
+ QtWidgets.QApplication.processEvents()
new_cb_stylesheet = '''
QCheckBox::indicator {
From a651444a1c243221e91dfcabae101cf43532062f Mon Sep 17 00:00:00 2001
From: ImLucasBrown <54835354+imlucasbrown@users.noreply.github.com>
Date: Sun, 4 May 2025 09:42:14 -0500
Subject: [PATCH 2/3] * Rebuilt the FONTS constant to be robust in cases where
no QApp is running.
---
nxt_editor/constants.py | 50 +++++++++++++++++++++++++++++++----------
1 file changed, 38 insertions(+), 12 deletions(-)
diff --git a/nxt_editor/constants.py b/nxt_editor/constants.py
index d98d763..6ab2edd 100644
--- a/nxt_editor/constants.py
+++ b/nxt_editor/constants.py
@@ -2,7 +2,7 @@
import os
import json
# External
-from Qt import QtGui
+from Qt import QtGui, QtWidgets
# Internal
from nxt.constants import USER_DIR
@@ -22,21 +22,47 @@ class EDITOR_VERSION(object):
VERSION = VERSION_STR
-class FONTS(object):
- DEFAULT_SIZE = 10
- # Load fonts once
- _font_db = QtGui.QFontDatabase()
- _roboto_id = _font_db.addApplicationFont(":/fonts/fonts/Roboto/Roboto-Regular.ttf")
- _mono_id = _font_db.addApplicationFont(":/fonts/fonts/RobotoMono/RobotoMono-Regular.ttf")
+class _FontManager:
+ def __init__(self):
+ self._initialized = False
+ self._font_db = QtGui.QFontDatabase()
+ self.DEFAULT_SIZE = 10
+ self._default_family = "Sans Serif"
+ self._code_family = "Monospace"
- # Get actual family names from font DB
- ROBOTO_FAMILY = _font_db.applicationFontFamilies(_roboto_id)[0] if _roboto_id != -1 else "Sans Serif"
- ROBOTO_MONO_FAMILY = _font_db.applicationFontFamilies(_mono_id)[0] if _mono_id != -1 else "Monospace"
+ def initialize(self):
+ if self._initialized:
+ return
+ if not QtWidgets.QApplication.instance():
+ return
+ roboto_id = self._font_db.addApplicationFont(":/fonts/fonts/Roboto/Roboto-Regular.ttf")
+ mono_id = self._font_db.addApplicationFont(":/fonts/fonts/RobotoMono/RobotoMono-Regular.ttf")
- DEFAULT_FAMILY = ROBOTO_FAMILY
- CODE_EDITOR_FAMILY = ROBOTO_MONO_FAMILY
+ if roboto_id != -1:
+ self._default_family = self._font_db.applicationFontFamilies(roboto_id)[0]
+ if mono_id != -1:
+ self._code_family = self._font_db.applicationFontFamilies(mono_id)[0]
+ self._initialized = True
+ @property
+ def DEFAULT_FAMILY(self):
+ self.initialize()
+ return self._default_family
+
+ @property
+ def MONOSPACE(self):
+ self.initialize()
+ return self._code_family
+
+ def default_font(self, size=None):
+ return QtGui.QFont(self.DEFAULT_FAMILY, size or self.DEFAULT_SIZE)
+
+ def monospace_font(self, size=None):
+ return QtGui.QFont(self.MONOSPACE, size or self.DEFAULT_SIZE)
+
+
+FONTS = _FontManager()
PREF_DIR_INT = EDITOR_VERSION.MAJOR
PREF_DIR_NAME = 'prefs'
_pref_dir_num = str(PREF_DIR_INT)
From d802ba9881ca65c02e44c9586373bef47062069c Mon Sep 17 00:00:00 2001
From: ImLucasBrown <54835354+imlucasbrown@users.noreply.github.com>
Date: Sun, 4 May 2025 09:43:13 -0500
Subject: [PATCH 3/3] ... Refactored how fonts are accessed to be consistent
and easier to maintain.
---
nxt_editor/dockwidgets/code_editor.py | 7 +++----
nxt_editor/dockwidgets/hotkey_editor.py | 9 +++++----
nxt_editor/dockwidgets/output_log.py | 13 +++++++------
nxt_editor/dockwidgets/property_editor.py | 5 +++--
nxt_editor/main_window.py | 2 +-
nxt_editor/node_graphics_item.py | 5 +++--
nxt_editor/stage_view.py | 5 +++--
7 files changed, 25 insertions(+), 21 deletions(-)
diff --git a/nxt_editor/dockwidgets/code_editor.py b/nxt_editor/dockwidgets/code_editor.py
index d85f33c..037c548 100644
--- a/nxt_editor/dockwidgets/code_editor.py
+++ b/nxt_editor/dockwidgets/code_editor.py
@@ -87,7 +87,7 @@ def __init__(self, title='Code Editor', parent=None, minimum_width=500):
self.name_layout.addWidget(self.name_edit_button, 0, QtCore.Qt.AlignLeft)
self.path_label = QtWidgets.QLabel(parent=self.details_frame)
- self.path_label.setFont(QtGui.QFont(FONTS.CODE_EDITOR_FAMILY, 8))
+ self.path_label.setFont(QtGui.QFont(FONTS.MONOSPACE, 8))
self.path_label.setStyleSheet('color: grey')
self.details_layout.addWidget(self.path_label)
@@ -601,9 +601,8 @@ def __init__(self, show_line_numbers=True, highlight_current_line=True,
self.setFocusPolicy(QtCore.Qt.ClickFocus)
# font settings
- self.font_family = FONTS.CODE_EDITOR_FAMILY
self.font_size = FONTS.DEFAULT_SIZE
- self.setFont(QtGui.QFont(self.font_family, self.font_size))
+ self.setFont(FONTS.monospace_font(self.font_size))
self.setLineWrapMode(QtWidgets.QPlainTextEdit.NoWrap)
# display settings
@@ -1312,7 +1311,7 @@ def __init__(self, parent=None):
def paintEvent(self, event):
painter = QtGui.QPainter()
painter.begin(self)
- painter.setFont(QtGui.QFont(FONTS.CODE_EDITOR_FAMILY, 14))
+ painter.setFont(QtGui.QFont(FONTS.MONOSPACE, 14))
font_metrics = QtGui.QFontMetrics(painter.font())
painter.setRenderHint(QtGui.QPainter.Antialiasing)
# actual_display_state
diff --git a/nxt_editor/dockwidgets/hotkey_editor.py b/nxt_editor/dockwidgets/hotkey_editor.py
index d7bc6a7..62debc3 100644
--- a/nxt_editor/dockwidgets/hotkey_editor.py
+++ b/nxt_editor/dockwidgets/hotkey_editor.py
@@ -6,6 +6,7 @@
# Internal
import nxt_editor
+from nxt_editor.constants import FONTS
from nxt_editor.dockwidgets.dock_widget_base import DockWidgetBase
from nxt_editor import colors, dialogs
@@ -28,14 +29,14 @@
'other shortcut.
')
TOOLTIP_STYLE = '''QToolTip {
- font-family: Roboto Mono;
+ font-family: %s;
background-color: #3E3E3E;
border: 1px solid #232323;
- }'''
+ }''' % (FONTS.MONOSPACE,)
TABLE_STYLE = '''QTableView {
- font-family: Roboto Mono;
- }'''
+ font-family: %s;
+ }''' % (FONTS.MONOSPACE,)
class HotkeyEditor(DockWidgetBase):
diff --git a/nxt_editor/dockwidgets/output_log.py b/nxt_editor/dockwidgets/output_log.py
index 0ec8508..95fb276 100644
--- a/nxt_editor/dockwidgets/output_log.py
+++ b/nxt_editor/dockwidgets/output_log.py
@@ -12,6 +12,7 @@
# Internal
import nxt_editor
from nxt_editor import user_dir
+from nxt_editor.constants import FONTS
from nxt_editor.dockwidgets.dock_widget_base import DockWidgetBase
from nxt import nxt_log
from nxt_editor import LoggingSignaler, colors
@@ -99,7 +100,7 @@ def format(self, record):
links = []
if links:
text = self.format_links(text, links)
- msg = '{}'.format(text)
+ msg = '{}'.format(FONTS.MONOSPACE, text)
if multi:
replacement = (msg, record.msg[1])
else:
@@ -377,10 +378,10 @@ def write_rich_output(self, val, level=None):
else:
text = val
color = colors.LOGGING_COLORS.get(level, 'white')
- html = ''.format(color)
+ html = ''.format(FONTS.MONOSPACE, color)
style = ("")
+ "pre {margin: 0; font-family: '%s';} "
+ "" % (FONTS.DEFAULT_FAMILY,))
text = style + ("{}".format(text))
html += text + ''
self.rich_output_textedit.insertHtml(html)
@@ -431,7 +432,7 @@ def __init__(self, parent):
self._parent = parent
self.setStyleSheet(self.parent().parent().styleSheet())
self.setReadOnly(True)
- self.setFont(QtGui.QFont('Roboto Mono', 10))
+ self.setFont(QtGui.QFont(FONTS.MONOSPACE, 10))
def contextMenuEvent(self, event):
menu = self.createStandardContextMenu()
@@ -447,7 +448,7 @@ def __init__(self, parent):
self.anchorClicked.connect(self.parent().link_clicked)
self.setStyleSheet(self.parent().parent().styleSheet())
self.setOpenLinks(False)
- self.setFont(QtGui.QFont('Roboto Mono', 10))
+ self.setFont(QtGui.QFont(FONTS.MONOSPACE, 10))
def contextMenuEvent(self, event):
menu = self.createStandardContextMenu()
diff --git a/nxt_editor/dockwidgets/property_editor.py b/nxt_editor/dockwidgets/property_editor.py
index 2c114e0..b492a5e 100644
--- a/nxt_editor/dockwidgets/property_editor.py
+++ b/nxt_editor/dockwidgets/property_editor.py
@@ -16,6 +16,7 @@
# Internal
from nxt_editor import user_dir
+from nxt_editor.constants import FONTS
from nxt_editor.dockwidgets.dock_widget_base import DockWidgetBase
from nxt_editor.pixmap_button import PixmapButton
from nxt_editor.label_edit import LabelEdit
@@ -1481,11 +1482,11 @@ def __init__(self, parent=None):
}
QToolTip {
- font-family: Roboto Mono;
+ font-family: %s;
color: white;
border: 1px solid #3E3E3E
}
- '''
+ ''' % (FONTS.MONOSPACE,)
self.setStyleSheet(style)
self._parent = parent
self.node_path_delegate = NodePathBtnDelegate(self)
diff --git a/nxt_editor/main_window.py b/nxt_editor/main_window.py
index b437220..2328c76 100644
--- a/nxt_editor/main_window.py
+++ b/nxt_editor/main_window.py
@@ -122,7 +122,7 @@ def __init__(self, filepath=None, parent=None, start_rpc=False):
style_file.open(QtCore.QFile.ReadOnly)
self.stylesheet = str(style_file.readAll())
self.setStyleSheet(self.stylesheet)
- self.setFont(QtGui.QFont(FONTS.DEFAULT_FAMILY, FONTS.DEFAULT_SIZE))
+ self.setFont(FONTS.default_font())
# nxt object in charge of loaded graphs
self.nxt = Session()
diff --git a/nxt_editor/node_graphics_item.py b/nxt_editor/node_graphics_item.py
index 128f4b7..845acb9 100644
--- a/nxt_editor/node_graphics_item.py
+++ b/nxt_editor/node_graphics_item.py
@@ -13,6 +13,7 @@
import nxt_editor
from nxt import nxt_path, nxt_node
from nxt.nxt_layer import LAYERS
+from nxt_editor.constants import FONTS
from . import colors
from nxt.stage import INTERNAL_ATTRS
from .label_edit import NameEditDialog
@@ -57,8 +58,8 @@ def __init__(self, model, node_path, view):
self.setAcceptHoverEvents(True)
# draw settings
- self.title_font = QtGui.QFont("Roboto Mono", 14)
- self.attr_font = QtGui.QFont("Roboto Mono", 9)
+ self.title_font = QtGui.QFont(FONTS.MONOSPACE, 14)
+ self.attr_font = QtGui.QFont(FONTS.MONOSPACE, 9)
self.title_rect_height = 39
self.attr_rect_height = 26
self.attr_rect_opacity = 0.9
diff --git a/nxt_editor/stage_view.py b/nxt_editor/stage_view.py
index d6ad664..d0f8680 100644
--- a/nxt_editor/stage_view.py
+++ b/nxt_editor/stage_view.py
@@ -13,6 +13,7 @@
# Interal
import nxt_editor
from nxt import nxt_node, tokens
+from nxt_editor.constants import FONTS
from nxt_editor.node_graphics_item import NodeGraphicsItem, NodeGraphicsPlug
from nxt_editor.connection_graphics_item import AttrConnectionGraphic
from nxt_editor.dialogs import NxtWarningDialog
@@ -265,14 +266,14 @@ def update_style_sheet(self):
light_color.setHsv(color_obj.hsvHue(), color_obj.hsvSaturation() * 0.3, color_obj.value())
style = '''
QToolTip {
- font-family: Roboto Mono;
+ font-family: %s;
background-color: %s
}
QRubberBand {
selection-background-color: %s
}
- ''' % (light_color.name(), layer_color)
+ ''' % (FONTS.DEFAULT_FAMILY, light_color.name(), layer_color)
self.setStyleSheet(style)
def clear(self):