From 9c0b971e790967fc3eeaa00764f8c883bd675a26 Mon Sep 17 00:00:00 2001 From: zqq-dora Date: Wed, 21 Oct 2026 15:33:26 +0800 Subject: [PATCH] fix(Menu): restore spacing between header and list when arrows are hidden MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PR #728 made ArrowListView's topMargin conditional on itemsView.interactive to avoid extra space when arrows are absent. However, that topMargin was also the only spacing between a search-box header and the menu items. When a menu had a header but no arrows (item count <= maxVisibleItems), the header and the first item were flush together with zero gap. Menu.qml - Add ids to the header and footer Loaders so their loaded state can be checked. - Add Layout.topMargin/bottomMargin on ArrowListView bound to whether the header/footer Loader actually has an item, so the 6px gap only appears when a header or footer is present, and never when absent. - Keep viewLayout spacing at 0 so menus without header/footer get no extra top/bottom padding. ArrowListView.qml - Set anchors.topMargin to 0 unconditionally; the header/list gap is now handled by Menu.qml's Layout.topMargin so the two do not stack. - Split topMargin out of the arrowStrips term in sizedHeight so it is always counted (it is now always 0 here, but kept for clarity). Only the Qt6 (qt6/src/qml/) implementation is changed; Qt5 is left unchanged as v25 ships Qt6 only. 修复带搜索框菜单在无箭头时搜索框与列表项之间缺少间距 PR #728 将 ArrowListView 的 topMargin 改为按 itemsView.interactive 条件 绑定,无箭头时归零。但该 topMargin 同时也是搜索框 header 与菜单项之间 唯一的间距来源,导致有 header 但无箭头(项数 <= maxVisibleItems)时, 搜索框与第一条菜单项贴在一起。 Menu.qml - 为 header 和 footer Loader 添加 id,以便检测其是否加载了内容。 - 在 ArrowListView 上添加 Layout.topMargin/bottomMargin,绑定到 header/footer Loader 是否有 item,使 6px 间距仅在 header/footer 存在时出现,不存在时不产生多余间距。 - viewLayout spacing 保持 0,无 header/footer 的菜单上下不会多出间距。 ArrowListView.qml - anchors.topMargin 无条件设为 0,header 与列表的间距改由 Menu.qml 的 Layout.topMargin 统一控制,避免两者叠加。 - sizedHeight 中将 topMargin 从 arrowStrips 项中拆出单独计入。 仅修改 Qt6(qt6/src/qml/)实现,Qt5 保持不变,v25 仅使用 Qt6。 --- qt6/src/qml/ArrowListView.qml | 9 +++++---- qt6/src/qml/Menu.qml | 4 ++++ 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/qt6/src/qml/ArrowListView.qml b/qt6/src/qml/ArrowListView.qml index 96ec7d7c1..b8f7e5db2 100644 --- a/qt6/src/qml/ArrowListView.qml +++ b/qt6/src/qml/ArrowListView.qml @@ -22,9 +22,10 @@ FocusScope { const item = itemsView.itemAtIndex(0) const measured = itemsView.contentHeight > 0 && item ? (item.height || item.implicitHeight) : 0 const showArrows = itemsView.count > maxVisibleItems - const arrowStrips = showArrows - ? 2 * (DS.Style.arrowListView.stepButtonSize.height + contentLayout.spacing) + contentLayout.anchors.topMargin : 0 - return Math.min(itemsView.count, maxVisibleItems) * (measured > 0 ? measured : itemHeight) + arrowStrips + const topMargin = contentLayout.anchors.topMargin + const extraHeight = topMargin + (showArrows + ? 2 * (DS.Style.arrowListView.stepButtonSize.height + contentLayout.spacing) : 0) + return Math.min(itemsView.count, maxVisibleItems) * (measured > 0 ? measured : itemHeight) + extraHeight } implicitWidth: Math.max(DS.Style.arrowListView.width, contentLayout.implicitWidth) @@ -33,7 +34,7 @@ FocusScope { ColumnLayout { id: contentLayout anchors.fill: parent - anchors.topMargin: itemsView.interactive ? 6 : 0 + anchors.topMargin: 0 spacing: itemsView.interactive ? 6 : 0 P.ArrowListViewButton { visible: itemsView.interactive diff --git a/qt6/src/qml/Menu.qml b/qt6/src/qml/Menu.qml index b3a07729b..73dcab34f 100644 --- a/qt6/src/qml/Menu.qml +++ b/qt6/src/qml/Menu.qml @@ -50,6 +50,7 @@ T.Menu { anchors.fill: parent Loader { + id: headerLoader Layout.fillWidth: true Layout.preferredHeight: height sourceComponent: control.header @@ -61,6 +62,8 @@ T.Menu { view.model: control.model Layout.fillWidth: true Layout.fillHeight: true + Layout.topMargin: headerLoader.item ? 6 : 0 + Layout.bottomMargin: footerLoader.item ? 6 : 0 view.currentIndex: control.currentIndex maxVisibleItems: control.maxVisibleItems itemHeight: DS.Style.menu.item.height @@ -89,6 +92,7 @@ T.Menu { } } Loader { + id: footerLoader Layout.fillWidth: true Layout.preferredHeight: height sourceComponent: control.footer