Skip to content

Commit 5edc15e

Browse files
committed
fix(ComboBox): fix the issue of highlighted state lingering after
mouse leaves menu items Root cause: The delegate.highlighted is bound to control.highlightedIndex (read-only). When the mouse leaves the popup area, this value is not automatically reset, causing the highlighted state to persist. Fix approach: - Add a new contentHovered property to the popup to track whether the mouse is within the popup list area - Use HoverHandler in Qt6 to synchronize the contentHovered state - Use MouseArea (acceptedButtons: Qt.NoButton) in Qt5 to synchronize the contentHovered state - Change delegate.highlighted to popup.contentHovered && control.highlightedIndex === index Log: Fixed the issue of lingering highlight on ComboBox menu items after mouse leaves Influence: ComboBox menu items fix(ComboBox): 修复菜单项鼠标离开后高亮残留问题 根因:delegate.highlighted 绑定 control.highlightedIndex(只读), 鼠标离开弹出区域时该值不会自动重置,导致高亮状态持续残留。 修复方案: - 为 popup 新增 contentHovered 属性,追踪鼠标是否在弹出列表区域内 - Qt6 版本使用 HoverHandler 同步 contentHovered 状态 - Qt5 版本使用 MouseArea(acceptedButtons: Qt.NoButton)同步 contentHovered 状态 - 将 delegate.highlighted 改为 popup.contentHovered && control.highlightedIndex === index Log: 修复ComboBox的菜单项鼠标离开后高亮残留问题 Influence: ComboBox菜单项 PMS: BUG-304991
1 parent 1998e42 commit 5edc15e

1 file changed

Lines changed: 81 additions & 2 deletions

File tree

qt6/src/qml/ComboBox.qml

Lines changed: 81 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ T.ComboBox {
1919
property int maxVisibleItems : DS.Style.comboBox.maxVisibleItems
2020
property D.Palette separatorColor: DS.Style.comboBox.edit.separator
2121
property var horizontalAlignment: control.flat ? Text.AlignRight : Text.AlignLeft
22+
property int keyboardNavIndex: -1
2223
opacity: enabled ? 1.0 : 0.4
2324

2425
implicitWidth: DS.Style.control.implicitWidth(control)
@@ -36,7 +37,9 @@ T.ComboBox {
3637
useIndicatorPadding: true
3738
text: control.textRole ? (Array.isArray(control.model) ? modelData[control.textRole] : (model[control.textRole] === undefined ? modelData[control.textRole] : model[control.textRole])) : modelData
3839
icon.name: (control.iconNameRole && model[control.iconNameRole] !== undefined) ? model[control.iconNameRole] : null
39-
highlighted: control.highlightedIndex === index
40+
highlighted: popup.contentHovered
41+
? control.highlightedIndex === index
42+
: control.keyboardNavIndex === index
4043
hoverEnabled: control.hoverEnabled
4144
autoExclusive: true
4245
checked: control.currentIndex === index
@@ -165,17 +168,93 @@ T.ComboBox {
165168

166169
popup: Popup {
167170
id: popup
171+
focus: true
168172
leftMargin: DS.Style.popup.margin
169173
rightMargin: DS.Style.popup.margin
170174
palette: control.palette
171175
implicitWidth: control.flat ? Math.max(contentItem.implicitWidth, control.width) : control.width
176+
property bool contentHovered: false
177+
property int lastHoveredIndex: -1
178+
onOpened: {
179+
control.keyboardNavIndex = -1
180+
popup.lastHoveredIndex = -1
181+
}
172182
contentItem: ArrowListView {
173183
clip: true
184+
focus: true
174185
maxVisibleItems: control.maxVisibleItems
175186
view.model: control.delegateModel
176-
view.currentIndex: control.highlightedIndex
187+
view.currentIndex: popup.contentHovered
188+
? control.highlightedIndex
189+
: control.keyboardNavIndex
177190
view.highlightRangeMode: ListView.ApplyRange
178191
view.highlightMoveDuration: 0
192+
Keys.priority: Keys.BeforeItem
193+
Keys.onPressed: (event) => {
194+
switch (event.key) {
195+
case Qt.Key_Down: {
196+
const cur = control.keyboardNavIndex >= 0 ? control.keyboardNavIndex
197+
: control.highlightedIndex >= 0 ? control.highlightedIndex
198+
: popup.lastHoveredIndex
199+
popup.contentHovered = false
200+
control.keyboardNavIndex = Math.min(cur + 1, control.count - 1)
201+
event.accepted = true
202+
break
203+
}
204+
case Qt.Key_Up: {
205+
const cur = control.keyboardNavIndex >= 0 ? control.keyboardNavIndex
206+
: control.highlightedIndex >= 0 ? control.highlightedIndex
207+
: popup.lastHoveredIndex
208+
popup.contentHovered = false
209+
control.keyboardNavIndex = Math.max(
210+
(cur >= 0 ? cur : control.count) - 1, 0)
211+
event.accepted = true
212+
break
213+
}
214+
case Qt.Key_Home:
215+
popup.contentHovered = false
216+
control.keyboardNavIndex = 0
217+
event.accepted = true
218+
break
219+
case Qt.Key_End:
220+
popup.contentHovered = false
221+
control.keyboardNavIndex = control.count - 1
222+
event.accepted = true
223+
break
224+
case Qt.Key_Return:
225+
case Qt.Key_Enter: {
226+
const idx = control.keyboardNavIndex >= 0
227+
? control.keyboardNavIndex
228+
: (popup.contentHovered ? control.highlightedIndex : -1)
229+
if (idx >= 0) {
230+
control.currentIndex = idx
231+
control.activated(idx)
232+
}
233+
popup.close()
234+
event.accepted = true
235+
break
236+
}
237+
}
238+
}
239+
HoverHandler {
240+
onHoveredChanged: {
241+
popup.contentHovered = hovered
242+
if (!hovered)
243+
control.keyboardNavIndex = -1
244+
}
245+
}
246+
Connections {
247+
target: control
248+
function onHighlightedIndexChanged() {
249+
if (control.highlightedIndex >= 0) {
250+
popup.lastHoveredIndex = control.highlightedIndex
251+
if (!popup.contentHovered) {
252+
popup.contentHovered = true
253+
control.keyboardNavIndex = -1
254+
}
255+
}
256+
}
257+
}
179258
}
180259

181260
background: FloatingPanel {

0 commit comments

Comments
 (0)