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
@@ -139,6 +139,7 @@ def main() -> int:
|
||||
win._toggle_nav()
|
||||
app.processEvents()
|
||||
fails += compare(theme_name, rail, opened, closed)
|
||||
fails += column_widths_do_not_move_icons(win, app, theme_name)
|
||||
|
||||
print()
|
||||
for f in fails:
|
||||
@@ -149,6 +150,63 @@ def main() -> int:
|
||||
os._exit(1 if fails else 0)
|
||||
|
||||
|
||||
def column_widths_do_not_move_icons(win, app, theme_name):
|
||||
"""The icon must not care how wide the column is.
|
||||
|
||||
On the machine that reported this the column matched the rail and the icons
|
||||
sat in the middle; in a test render the column stayed wider than the view
|
||||
and the same code drew them at the left. So sweep the width and require the
|
||||
icon to hold still.
|
||||
"""
|
||||
from PySide6.QtWidgets import QStyle, QStyleOptionViewItem
|
||||
|
||||
if not win._nav_collapsed:
|
||||
win._toggle_nav()
|
||||
app.processEvents()
|
||||
fails, seen = [], {}
|
||||
# The invariant that matters. A centred decoration is the only way Qt can
|
||||
# put a label-less row's icon anywhere but the left edge, and how far it
|
||||
# travels depends on the box the column hands it — which is why this
|
||||
# reproduces on one machine and not another. Require the instruction
|
||||
# itself, not just the pixel it happens to produce here.
|
||||
from PySide6.QtCore import Qt as _Qt
|
||||
for tree_name in ("nav", "nav_bottom"):
|
||||
tree = getattr(win, tree_name)
|
||||
index = tree.indexFromItem(tree.topLevelItem(0), 0)
|
||||
opt = QStyleOptionViewItem()
|
||||
tree.initViewItemOption(opt)
|
||||
tree.itemDelegate().initStyleOption(opt, index)
|
||||
align = int(opt.decorationAlignment)
|
||||
if align & int(_Qt.AlignHCenter) or not align & int(_Qt.AlignLeft):
|
||||
fails.append(f"{theme_name} {tree_name}: decorationAlignment={align}"
|
||||
f" — icon is free to drift off the left edge")
|
||||
for tree_name in ("nav", "nav_bottom"):
|
||||
tree = getattr(win, tree_name)
|
||||
keep = tree.columnWidth(0)
|
||||
for width in (tree.viewport().width(), 70, 100, 140):
|
||||
tree.setColumnWidth(0, width)
|
||||
app.processEvents()
|
||||
index = tree.indexFromItem(tree.topLevelItem(0), 0)
|
||||
opt = QStyleOptionViewItem()
|
||||
tree.initViewItemOption(opt)
|
||||
opt.rect = tree.visualRect(index)
|
||||
tree.itemDelegate().initStyleOption(opt, index)
|
||||
x = tree.style().subElementRect(
|
||||
QStyle.SE_ItemViewItemDecoration, opt, tree).left()
|
||||
seen.setdefault(tree_name, []).append((width, x))
|
||||
tree.setColumnWidth(0, keep)
|
||||
app.processEvents()
|
||||
xs = {x for _w, x in seen[tree_name]}
|
||||
if len(xs) > 1:
|
||||
fails.append(f"{theme_name} {tree_name}: icon x changes with the "
|
||||
f"column width — {seen[tree_name]}")
|
||||
print(f" column sweep: " + " ".join(
|
||||
f"{n}={[x for _w, x in v]}" for n, v in seen.items()))
|
||||
win._toggle_nav()
|
||||
app.processEvents()
|
||||
return fails
|
||||
|
||||
|
||||
def compare(theme_name, rail, opened, closed):
|
||||
print()
|
||||
print(f"theme={theme_name}")
|
||||
|
||||
Reference in New Issue
Block a user