From 1faf91bdb052b93ecd5b8d955cc8b7f50a163251 Mon Sep 17 00:00:00 2001 From: Urban Wallasch Date: Tue, 22 Jun 2021 11:41:51 +0200 Subject: [PATCH] * Optimized zFlowLayout() for speed. --- kanjidic.py | 93 ++++++++++++++++------------------------------------- 1 file changed, 28 insertions(+), 65 deletions(-) diff --git a/kanjidic.py b/kanjidic.py index 07bc156..27e7ebf 100755 --- a/kanjidic.py +++ b/kanjidic.py @@ -320,13 +320,11 @@ class zQTextEdit(QTextEdit): self._restore_cursor() # adapted from Qt flow layout C++ example +# stripped down and optimized for speed in our special use case class zFlowLayout(QLayout): - def __init__(self, parent: QWidget=None, margin: int=-1, hSpacing: int=-1, vSpacing: int=-1): + def __init__(self, parent=None): super().__init__(parent) self.itemList = list() - self.m_hSpace = hSpacing - self.m_vSpace = vSpacing - self.setContentsMargins(margin, margin, margin, margin) def addItem(self, item): self.itemList.append(item) @@ -351,30 +349,6 @@ class zFlowLayout(QLayout): except: return None - def horizontalSpacing(self): - if self.m_hSpace >= 0: - return self.m_hSpace - else: - return self.smartSpacing(QStyle.PM_LayoutHorizontalSpacing) - - def verticalSpacing(self): - if self.m_vSpace >= 0: - return self.m_vSpace - else: - return self.smartSpacing(QStyle.PM_LayoutVerticalSpacing) - - def smartSpacing(self, pm): - parent = self.parent() - if not parent: - return -1 - elif parent.isWidgetType(): - return parent.style().pixelMetric(pm, None, parent) - else: - return parent.spacing() - - def expandingDirections(self): - return Qt.Orientations(Qt.Orientation(0)) - def hasHeightForWidth(self): return True @@ -383,45 +357,34 @@ class zFlowLayout(QLayout): return height def setGeometry(self, rect): - super().setGeometry(rect) self.doLayout(rect, False) def sizeHint(self): - return self.minimumSize() - - def minimumSize(self): - size = QSize() - for item in self.itemList: - size = size.expandedTo(item.minimumSize()) - margins = self.contentsMargins() - size += QSize(margins.left() + margins.right(), margins.top() + margins.bottom()) - return size - - def doLayout(self, rect, testOnly): - left, top, right, bottom = self.getContentsMargins() - effectiveRect = rect.adjusted(+left, +top, -right, -bottom) - x = effectiveRect.x() - y = effectiveRect.y() - lineHeight = 0 - for item in self.itemList: - wid = item.widget() - spaceX = self.horizontalSpacing() - if spaceX == -1: - spaceX = wid.style().layoutSpacing(QSizePolicy.PushButton, QSizePolicy.PushButton, Qt.Horizontal) - spaceY = self.verticalSpacing() - if spaceY == -1: - spaceY = wid.style().layoutSpacing(QSizePolicy.PushButton, QSizePolicy.PushButton, Qt.Vertical) - nextX = x + item.sizeHint().width() + spaceX - if nextX - spaceX > effectiveRect.right() and lineHeight > 0: - x = effectiveRect.x() - y = y + lineHeight + spaceY - nextX = x + item.sizeHint().width() + spaceX - lineHeight = 0 - if not testOnly: - item.setGeometry(QRect(QPoint(x, y), item.sizeHint())) + return QSize() + + def doLayout(self, rect, testonly): + if not self.count(): + return 0 + x = rect.x() + y = rect.y() + right = rect.right() + 1 + iszhint = self.itemList[0].widget().sizeHint() + iwidth = iszhint.width() + iheight = iszhint.height() + ngaps = int(right / iwidth) + gap = 0 if ngaps < 1 else int((right % iwidth) / ngaps) + for i in range(self.count()): + nextX = x + iwidth + if nextX > right: + x = rect.x() + y = y + iheight + nextX = x + iwidth + gap + else: + nextX += gap + if not testonly: + self.itemList[i].setGeometry(QRect(QPoint(x, y), iszhint)) x = nextX - lineHeight = max(lineHeight, item.sizeHint().height()) - return y + lineHeight - rect.y() + bottom + return y + iheight - rect.y() class zFlowScrollArea(QScrollArea): @@ -437,7 +400,7 @@ class zFlowScrollArea(QScrollArea): self.clear() pane = QWidget() self.setWidget(pane) - layout = zFlowLayout(pane, 0, 0, 0) + layout = zFlowLayout(pane) layout.setEnabled(False) for tl in tiles: layout.addWidget(tl) @@ -451,7 +414,7 @@ class zFlowScrollArea(QScrollArea): else: pane = QWidget() self.setWidget(pane) - layout = zFlowLayout(pane, 0, 0, 0) + layout = zFlowLayout(pane) for idx in range(layout.count()): if layout.itemAt(idx).widget().text() == w.text(): layout.takeAt(idx) -- 2.30.2