#qt #qml #carousel #qt6
Вопрос:
Я написал простую карусель на QML. Я запускаю Qt 6.2.0 под Ubuntu 20.04.
import QtQuick
PathView {
id: view
property int item_width: 864
property int item_gap: 250
anchors.fill: parent
anchors.bottomMargin: 150
anchors.topMargin: 50
pathItemCount: 3
preferredHighlightBegin: 0.5
preferredHighlightEnd: 0.5
highlightRangeMode: PathView.StrictlyEnforceRange
highlightMoveDuration: 1000
snapMode: PathView.SnapToItem
rotation: -90
model: modelContent
delegate: DelegateContent { }
path: Path {
startX: -item_gap; startY: view.height / 2
PathAttribute { name: "iconScale"; value: 0.7 }
PathAttribute { name: "iconOpacity"; value: 0.1 }
PathAttribute { name: "iconOrder"; value: 0 }
PathLine {x: view.width / 2; y: view.height / 2; }
PathAttribute { name: "iconScale"; value: 1 }
PathAttribute { name: "iconOpacity"; value: 1 }
PathAttribute { name: "iconOrder"; value: 9 }
PathLine {x: view.width item_gap; y: view.height / 2; }
}
Component.onCompleted: {
gesture.gestureFired.connect(gestureFired)
}
onCurrentIndexChanged: {
itemAtIndex(0).visible = currentIndex < (count - 1)
}
function gestureFired(type) {
switch (type) {
case 1:
if (view.currentIndex > 0) view.decrementCurrentIndex();
break;
case 2:
if (view.currentIndex < view.count - 1) view.incrementCurrentIndex();
break;
}
}
}
Это работает очень хорошо. Изменение текущего индекса выполняется только программно ( gestureFired
сигнал с C ). Как вы можете видеть, кругового поведения не существует.
Следовательно, я хочу скрыть первый элемент (когда выбран последний) или последний элемент (когда выбран первый).
Я попробовал использовать приведенный выше код:
onCurrentIndexChanged: {
itemAtIndex(0).visible = currentIndex < (count - 1)
}
Идея заключается в следующем: если currentIndex
это последний элемент ( = count - 1
) visible
, свойство первого элемента должно быть ложным.
Но это не работает:
Ошибка типа: Значение равно нулю и не может быть преобразовано в объект
О какой «Ценности» идет речь? Я отладил currentIndex
и count
, и они оба действительны (4 и 5).
Какой правильный способ добиться такого поведения?
Комментарии:
1. Я не согласен на изменение тега с
qt5
наqt6
.qt5
имеет 1,6 тыс. наблюдателей,qt6
всего 31! И различия не так уж велики…2. Qt6 вносит большие изменения, поэтому это не Qt 5.16, а Qt 6. Так что лучше использовать этот тег. Если вы хотите обратиться к наблюдателям, посмотрите на соответствующий тег Qt, который имеет 21,7 тыс. Другие теги обычно указывают среду. С другой стороны, если вы проверите активность сообщества Qt в SO, вы увидите, что нас немного (вероятно, меньше 50).
Ответ №1:
Простое решение состоит в том, чтобы выполнить привязку в делегате:
import QtQuick
Column {
id: root
required property int index
// mapping model roles
required property string name
visible: _internals.calculateVisibility()
QtObject {
id: _internals
function calculateVisibility() {
console.log(index, root.PathView.isCurrentItem, root.PathView.view.currentIndex)
if ((root.index === (root.PathView.view.count - 1)) amp;amp; (root.PathView.view.currentIndex === 0))
return false;
else if ((root.index === 0) amp;amp; (root.PathView.view.currentIndex === (root.PathView.view.count - 1)))
return false;
return true;
}
}
Text {
id: nameText
text: root.name
font.pointSize: 16
color: root.PathView.isCurrentItem ? "red" : "blue"
}
}
Комментарии:
1. Из любопытства, какова цель встраивания a
function
в aQtObject
? Я могу заявить об этом даже без этого, и, похоже, это тоже работает.2. Ваше решение почти сработало! Единственное предостережение заключается в том, что при изменении текущего индекса (перемещении элемента) ранее скрытый делегат теперь виден! И это неприятно видеть.
3. @Mark Идея состоит в том, чтобы скрыть функции, которые не должны быть общедоступными. Это та же самая причина, потому что в C есть публичное, защищенное и частное.
4. В качестве уродливого обходного пути я добавил
Timer
, что задерживает переключениеroot.visibility
сfalse
true
одного и того же количестваview.highlightMoveDuration