From 521469185e7db8295785f5deb71fddfc8d69b5c4 Mon Sep 17 00:00:00 2001 From: zhangkun Date: Mon, 28 Sep 2026 18:33:23 +0800 Subject: [PATCH] fix(ComboBox): size popup before it is mapped MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. Size the window popup from the model and the measured delegate height, instead of the content item, which has not been laid out yet when the window is created. 2. Measure the delegate height in ArrowListView by realizing one item while the popup is still closed, and pin the scroll-arrow height so the layout settles in one pass. 3. Keep the style item height only as the viewport that makes that first measurement possible. Log: ComboBox popups appear at their final size instead of being resized after being mapped. Influence: Removes the popup size jump with Window popup type. fix(ComboBox): 弹窗按最终尺寸显示 1. 窗口弹窗改用模型与实测行高计算尺寸,不再使用尚未布局的内容项。 2. ArrowListView 在弹窗关闭时提前实例化一项以量出行高,并固定箭头条高度,使布局一次到位。 3. 样式行高仅作为首次测量所需的引导视口。 Log: 下拉弹窗显示时即为其最终尺寸,不再在显示后改变尺寸。 PMS: BUG-370839 Influence: 修复 Window 类型弹窗的尺寸跳动。 --- qt6/src/qml/ArrowListView.qml | 16 ++++++++++++++-- qt6/src/qml/ComboBox.qml | 3 +++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/qt6/src/qml/ArrowListView.qml b/qt6/src/qml/ArrowListView.qml index f6b2eace5..eb7c880c2 100644 --- a/qt6/src/qml/ArrowListView.qml +++ b/qt6/src/qml/ArrowListView.qml @@ -15,6 +15,17 @@ FocusScope { property int itemHeight: DS.Style.arrowListView.itemHeight property alias view: itemsView + // Full height of the list, to size a popup before it is mapped. + readonly property real sizedHeight: { + if (itemsView.count === 0) + return 0 + const item = itemsView.itemAtIndex(0) + const measured = itemsView.contentHeight > 0 && item ? (item.height || item.implicitHeight) : 0 + const arrowStrips = itemsView.count > maxVisibleItems + ? 2 * (DS.Style.arrowListView.stepButtonIconSize.height + contentLayout.spacing) : 0 + return Math.min(itemsView.count, maxVisibleItems) * (measured > 0 ? measured : itemHeight) + arrowStrips + } + implicitWidth: Math.max(DS.Style.arrowListView.width, contentLayout.implicitWidth) implicitHeight: contentLayout.implicitHeight @@ -25,7 +36,7 @@ FocusScope { visible: itemsView.interactive Layout.alignment: Qt.AlignHCenter Layout.fillWidth: true - Layout.preferredHeight: implicitHeight + Layout.preferredHeight: DS.Style.arrowListView.stepButtonIconSize.height view: itemsView stepSize: control.itemHeight direction: P.ArrowListViewButton.UpButton @@ -36,6 +47,7 @@ FocusScope { clip: true Layout.fillWidth: true Layout.fillHeight: true + onHeightChanged: if (height > 0 && contentHeight === 0) forceLayout() implicitHeight: itemsView.count > 0 ? Math.min(contentHeight, maxVisibleItems * contentHeight / itemsView.count) : 0 implicitWidth:{ var maxWidth = DS.Style.arrowListView.width @@ -81,7 +93,7 @@ FocusScope { visible: itemsView.interactive Layout.alignment: Qt.AlignHCenter Layout.fillWidth: true - Layout.preferredHeight: implicitHeight + Layout.preferredHeight: DS.Style.arrowListView.stepButtonIconSize.height view: itemsView stepSize: control.itemHeight direction: P.ArrowListViewButton.DownButton diff --git a/qt6/src/qml/ComboBox.qml b/qt6/src/qml/ComboBox.qml index cb35c3c38..9f3d53416 100644 --- a/qt6/src/qml/ComboBox.qml +++ b/qt6/src/qml/ComboBox.qml @@ -173,6 +173,9 @@ T.ComboBox { rightMargin: DS.Style.popup.margin palette: control.palette implicitWidth: control.flat ? Math.max(contentItem.implicitWidth, control.width) : control.width + // 60 is a temporary viewport so the list can realize one row and be measured. + implicitHeight: (contentItem.sizedHeight > 0 ? contentItem.sizedHeight : 2 * DS.Style.arrowListView.itemHeight) + + topPadding + bottomPadding onClosed: control.isInteractingWithContent = false Connections { target: control