fix(ui): tách hàng Cài đặt khỏi nhóm menu ngay trên nó
CI / test (pull_request) Canceled after 0s

Thanh rail đặt setSpacing(0) nên nút Cài đặt dán sát Dashboard/Giám sát, ba
dòng đọc thành một khối. Thêm hằng _NAV_SETTINGS_GAP trong rail_metrics và
xin khe bằng nvl.addSpacing() — margin trong QSS vẽ BÊN TRONG hộp widget, mà
nút này bị _rebuild_nav ghim đúng chiều cao một dòng menu nên margin không
mua được pixel nào.

Rút gọn lại comment ở _rebuild_nav cho khớp.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-09-08 21:27:28 +09:00
co-authored by Claude Opus 5
parent 0efc4bbf0e
commit c05de8054a
3 changed files with 18 additions and 14 deletions
+6 -13
View File
@@ -251,24 +251,17 @@ class NavRailMixin:
blocked = tree.blockSignals(True)
tree.addTopLevelItem(it)
tree.blockSignals(blocked)
# Both destination lists are exactly as tall as their rows; the
# stretch in between belongs to RECENTS.
#
# The frame, and nothing else. A flat ``+ 8`` here used to leave 6px
# of dead space under the last row of each list, and because the
# Settings button sits DIRECTLY under nav_bottom (nvl has no
# spacing), that space landed between Giám sát and Settings only —
# so three rows that read as one list were spaced 18/26px. Padding
# a row is the item delegate's job; this is the frame's.
# Rows plus frame, nothing else: the flat ``+ 8`` this replaces
# left 6px of dead space under the last row, and since Settings
# sits directly under nav_bottom it fell between Giám sát and
# Settings alone — 18/26px for rows that read as one list.
row_h = 0
for tree in (self.nav, self.nav_bottom):
n = tree.topLevelItemCount()
row_h = tree.sizeHintForRow(0) if n else row_h
tree.setFixedHeight(n * row_h + 2 * tree.frameWidth())
# Settings is one more row of the same list, so it gets the rows'
# own height rather than a second set of paddings guessed to match
# it — the only way the three stay evenly spaced when the font (and
# with it ``sizeHintForRow``) is not the one this was tuned on.
# Settings is one more row of the list, so it takes the rows' own
# height instead of paddings guessed to match it.
if row_h and hasattr(self, "_nav_settings_btn"):
self._nav_settings_btn.setFixedHeight(row_h)
if keep:
+5
View File
@@ -15,6 +15,11 @@ _NAV_EXPANDED_WIDTH = 232
_NAV_COLLAPSED_WIDTH = 54
_NAV_ROW_INSET = 4
_NAV_ROW_GAP = 6
# Khe TRÊN nút Cài đặt, tính bằng khoảng trống thật trong layout của rail.
# Không đặt bằng ``margin`` trong QSS: margin của stylesheet được vẽ BÊN TRONG
# hộp của widget, mà nút này lại bị ``_rebuild_nav`` ghim đúng chiều cao một
# dòng menu — nên margin không mua được một pixel khoảng cách nào.
_NAV_SETTINGS_GAP = 10
# 132 -> 232: o 132px nhan "Cuoc tro chuyen moi" bi cat mat chu. San phai du
# rong cho nhan DAI NHAT tren thanh, khong phai cho nhan trung binh.
_NAV_MIN_WIDTH = 232
+7 -1
View File
@@ -35,7 +35,7 @@ class TopBarMixin:
from PySide6.QtWidgets import QHBoxLayout, QLabel, QPushButton
from ...i18n import tr
from ...ui.icons import icon as _icon
from .rail_metrics import _NAV_ROW_GAP, _NAV_ROW_INSET
from .rail_metrics import _NAV_ROW_GAP, _NAV_ROW_INSET, _NAV_SETTINGS_GAP
# Bottom-pinned group: the places you visit occasionally, kept out of the
# way of the ones you live in. A hairline (styled via #navrailBottom in
@@ -71,6 +71,12 @@ class TopBarMixin:
# The first _rebuild_nav() ran before this button existed (it is what
# fills the list this row belongs under), so take the height here too.
self._nav_settings_btn.setFixedHeight(self.nav_bottom.sizeHintForRow(0))
# Khe TRÊN hàng Cài đặt, xin thẳng từ layout — thanh rail đặt
# ``setSpacing(0)`` nên không có khoảng nào sẵn, và margin trong QSS thì
# không mua được pixel nào (xem ``_NAV_SETTINGS_GAP``). Cài đặt là việc
# khác với nhóm Dashboard/Giám sát ngay trên nó; dán sát vào thì hai thứ
# đọc thành một khối.
nvl.addSpacing(_NAV_SETTINGS_GAP)
nvl.addWidget(self._nav_settings_btn)
self._account_row = self._build_account_row()