From 66d4dd8f3507edecf61598f5e342698dd8a8a9d1 Mon Sep 17 00:00:00 2001 From: Benjamin Johnson <42893476+bmjcode@users.noreply.github.com> Date: Sun, 24 May 2026 10:16:16 -0400 Subject: [PATCH 1/3] Use __slots__ to save memory in the Link classes This can reduce Frescobaldi's memory usage by several megabytes when displaying a large score since each point-and-click link is associated with its own Link object. --- qpageview/link.py | 19 +++++++------------ qpageview/pdf.py | 2 ++ 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/qpageview/link.py b/qpageview/link.py index 334a07c..54e6697 100644 --- a/qpageview/link.py +++ b/qpageview/link.py @@ -40,21 +40,16 @@ class Link: - fileName = "" - isExternal = False - targetPage = -1 - url = "" - tooltip = "" - area = Area(0, 0, 0, 0) + __slots__ = ( + "fileName", "isExternal", "targetPage", "url", "tooltip", "area") def __init__(self, left, top, right, bottom, url=None, tooltip=None): + self.fileName = "" self.area = Area(left, top, right, bottom) - if url: - self.url = url - if "://" in url: - self.isExternal = True - if tooltip: - self.tooltip = tooltip + self.url = url or "" + self.isExternal = ("://" in self.url) + self.tooltip = tooltip or "" + self.targetPage = -1 def rect(self): """Return the area attribute as a QRectF().""" diff --git a/qpageview/pdf.py b/qpageview/pdf.py index d94f737..ac0c9f9 100644 --- a/qpageview/pdf.py +++ b/qpageview/pdf.py @@ -51,6 +51,8 @@ class Link(link.Link): """A link that encapsulates QPdfLinkModel data.""" + __slots__ = ("_targetPage", "_url") + def __init__(self, linkobj, index, pointSize): self._targetPage = linkobj.data(index, QPdfLinkModel.Role.Page.value) self._url = linkobj.data(index, From d8ceb3b079286ab347561e32ca4609e5f9e5591c Mon Sep 17 00:00:00 2001 From: Benjamin Johnson <42893476+bmjcode@users.noreply.github.com> Date: Sun, 24 May 2026 10:23:15 -0400 Subject: [PATCH 2/3] Use __slots__ to save memory in the Rectangles class This further reduces memory usage since each page has an associated link.Links object, which is derived from Rectangles. --- qpageview/rectangles.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/qpageview/rectangles.py b/qpageview/rectangles.py index ad835c4..38b7894 100644 --- a/qpageview/rectangles.py +++ b/qpageview/rectangles.py @@ -51,6 +51,8 @@ class Rectangles: once. x should be < x2 and y should be < y2. """ + __slots__ = ("_items", "_index") + def __init__(self, objects=None): """Initializes the Rectangles object. From 92b1c0333824a80a1984028ba0a817fd2c053c3b Mon Sep 17 00:00:00 2001 From: Benjamin Johnson <42893476+bmjcode@users.noreply.github.com> Date: Sun, 24 May 2026 10:33:25 -0400 Subject: [PATCH 3/3] Use __slots__ in a couple more simple internal classes --- qpageview/backgroundjob.py | 2 ++ qpageview/cache.py | 2 ++ qpageview/util.py | 2 ++ 3 files changed, 6 insertions(+) diff --git a/qpageview/backgroundjob.py b/qpageview/backgroundjob.py index 6c8768d..378da8f 100644 --- a/qpageview/backgroundjob.py +++ b/qpageview/backgroundjob.py @@ -105,6 +105,8 @@ class SingleRun: old one finishes. """ + __slots__ = ("_job") + def __init__(self): self._job = None diff --git a/qpageview/cache.py b/qpageview/cache.py index 9e7411e..955bbc0 100644 --- a/qpageview/cache.py +++ b/qpageview/cache.py @@ -28,6 +28,8 @@ class ImageEntry: + __slots__ = ("image", "bcount", "time") + def __init__(self, image): self.image = image self.bcount = image.sizeInBytes() diff --git a/qpageview/util.py b/qpageview/util.py index 26ecd21..fb54142 100644 --- a/qpageview/util.py +++ b/qpageview/util.py @@ -80,6 +80,8 @@ def rect(self): class MapToPage: """Simple class wrapping a QTransform to map rect and point to page coordinates.""" + __slots__ = ("t") + def __init__(self, transform): self.t = transform