I am currently struggling to combine two seemingly simple concepts: alternating row colors and a smooth moving highlight item in QML ListViews.
Consider this simple example:
import sysfrom PySide6.QtCore import QUrlfrom PySide6.QtQml import QQmlApplicationEnginefrom PySide6.QtWidgets import QApplicationif __name__ == '__main__': app = QApplication([]) engine = QQmlApplicationEngine() engine.load(QUrl.fromLocalFile('main.qml')) if not engine.rootObjects(): sys.exit(-1) app.exec()
import QtQuickimport QtQuick.Controls.Materialimport QtQuick.LayoutsApplicationWindow { id: root width: 400 height: 500 visible: true font.family: 'Noto Sans' ListView { id: listView width: root.width height: root.height clip: true focus: true reuseItems: true boundsBehavior: Flickable.StopAtBounds model: ["Wikipedia is a free online encyclopedia","Wikipedia is a free online encyclopedia","Wikipedia is a free online encyclopedia","Wikipedia is a free online encyclopedia","Wikipedia is a free online encyclopedia","Wikipedia is a free online encyclopedia","Wikipedia is a free online encyclopedia","Wikipedia is a free online encyclopedia","Wikipedia is a free online encyclopedia" ] delegate: Rectangle { height: 40 width: parent.width color: ListView.isCurrentItem ? Material.accent : index % 2 === 0 ? palette.base : palette.alternateBase MouseArea { anchors.fill: parent onClicked: { listView.currentIndex = index } } RowLayout { height: parent.height Label { text: index horizontalAlignment: Qt.AlignHCenter verticalAlignment: Qt.AlignVCenter Layout.preferredWidth: 100 } Label { text: modelData Layout.preferredWidth: 300 } } } }}
Here, we have a ListView and a delegate with alternating row colors. We can highlight the item by either clicking on it or using the arrow keys:
It's also quite simple to achieve a smooth highlighting (without alternating row colors) by swapping out just a few lines of code:
// ...highlight: Rectangle { height: 40 width: parent.width color: Material.accent}delegate: Rectangle { height: 40 width: parent.width color: 'transparent' // ...}// ...
In isolation, both of these concepts are easy to apply but when combining them, the struggle gets real 😅
Attempt #1
// ...highlight: Rectangle { height: 40 width: parent.width color: Material.accent}delegate: Rectangle { height: 40 width: parent.width color: ListView.isCurrentItem ? 'transparent' : index % 2 === 0 ? palette.base : palette.alternateBase // ...}// ...
results in
Attempt #2
// ...highlight: Rectangle { height: 40 width: parent.width color: Material.accent z: 1}delegate: Rectangle { height: 40 width: parent.width color: index % 2 === 0 ? palette.base : palette.alternateBase // ...}// ...
results in
I often find myself believing that this task shouldn't be overly difficult to accomplish, yet I can't shake the feeling that I might be overlooking something. Has anyone else encountered a similar issue and discovered a solution?