Pin rail row icons to the left edge instead of letting Qt centre them
QStyledItemDelegate hands the style decorationAlignment = AlignHCenter | AlignVCenter. For a row with a label that is invisible — the icon sits left of the text either way — but every rail row loses its label when the rail collapses to 54px, and a centred decoration then lands wherever the column happens to leave room. _NavItemDelegate overrides it to AlignLeft, so the icon is on the row's left padding regardless of column width, style or platform. Honest limit: this was reported from the running app and I could not reproduce it offscreen — sweeping the column width leaves the icon at a fixed x with or without the delegate. What is verifiable is the instruction, and centring is the only mechanism by which Qt can put a label-less row's icon anywhere but the left. check_rail_align now asserts the flag itself, which fails (132) the moment the delegate is removed, alongside the column sweep. Settings follows the rows to their new inset (padding-left 7px → 4px). Its label still sat 3px left of Dashboard's because a button leaves less air between icon and label than a tree row does; a 19px icon box closes that to 1px, with the 16px glyph left-aligned inside it. 15/15 checkers pass, no flakes this run. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
d060d5679a
commit
cb03bc1494
@@ -9,6 +9,7 @@ from typing import List
|
||||
from PySide6.QtCore import Qt, QTimer
|
||||
from PySide6.QtGui import QGuiApplication, QIcon
|
||||
from PySide6.QtWidgets import (
|
||||
QStyledItemDelegate,
|
||||
QApplication, QComboBox, QHBoxLayout, QLabel, QMainWindow, QMenu,
|
||||
QPushButton, QScrollArea, QSizePolicy, QSplitter, QStackedWidget,
|
||||
QSystemTrayIcon, QToolButton, QTreeWidget, QTreeWidgetItem, QVBoxLayout,
|
||||
@@ -79,6 +80,23 @@ class _Toast(QLabel):
|
||||
self._timer.start(ms)
|
||||
|
||||
|
||||
class _NavItemDelegate(QStyledItemDelegate):
|
||||
"""Keep a rail row's icon on the left edge, whatever the column is doing.
|
||||
|
||||
QStyledItemDelegate hands the style decorationAlignment = AlignHCenter, so
|
||||
a row with no label — every row once the rail collapses to 54px — has its
|
||||
icon centred inside whatever box the column happens to give it. That box
|
||||
tracks the column width, which is not stable: stretched to the viewport the
|
||||
icons land in the middle of the rail, while a column left wider than the
|
||||
view leaves them at the left. Same code, two different pictures, which is
|
||||
why a test render disagreed with the running app.
|
||||
"""
|
||||
|
||||
def initStyleOption(self, option, index):
|
||||
super().initStyleOption(option, index)
|
||||
option.decorationAlignment = Qt.AlignLeft | Qt.AlignVCenter
|
||||
|
||||
|
||||
class MainWindow(QMainWindow):
|
||||
# Nav rows (Dashboard/Schedule/Monitoring are lazy; Workspace is the eager home page).
|
||||
_ROW_DASHBOARD, _ROW_SCHEDULE, _ROW_WORKSPACE, _ROW_MONITORING = 0, 1, 2, 3
|
||||
@@ -448,13 +466,14 @@ class MainWindow(QMainWindow):
|
||||
tree.setIndentation(0)
|
||||
tree.setRootIsDecorated(False)
|
||||
tree.setUniformRowHeights(True)
|
||||
# The column follows the viewport instead of the widest label. Left
|
||||
# to size itself it stayed ~100px wide inside the 54px collapsed
|
||||
# rail, so a horizontal scrollbar appeared and slid the icons out of
|
||||
# the position they hold while the rail is open.
|
||||
from PySide6.QtWidgets import QHeaderView
|
||||
tree.header().setSectionResizeMode(0, QHeaderView.Stretch)
|
||||
tree.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
|
||||
# The column follows the viewport instead of the widest label. Left
|
||||
# to size itself it stayed ~100px wide inside the 54px collapsed
|
||||
# rail, so a horizontal scrollbar appeared and slid the icons out of
|
||||
# the position they hold while the rail is open.
|
||||
from PySide6.QtWidgets import QHeaderView
|
||||
tree.header().setSectionResizeMode(0, QHeaderView.Stretch)
|
||||
tree.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
|
||||
tree.setItemDelegate(_NavItemDelegate(tree))
|
||||
return tree
|
||||
|
||||
def _nav_rows(self):
|
||||
|
||||
Reference in New Issue
Block a user