Попытка центрировать элементы программно в ListView
Я хотел бы иметь центрированные элементы в QML ListView
и поэтому я добавил следующий код моего ListView
:
import QtQuick 2.0
import QtMultimedia 5.5
import QtQuick.Controls 1.3
import QtQuick.Extras 1.4
import QtQuick.Layouts 1.2
import QtQuick.Window 2.2
import QtTest 1.1
Rectangle {
id: ueKeypad
width: ueMainColumnLayout.implicitWidth+2*radius
height: ueMainColumnLayout.implicitHeight+2*radius
color: "grey"
radius: 8
border.color: "#99c6f0"
border.width: 4
ColumnLayout {
id: ueMainColumnLayout
anchors.fill: parent
anchors.margins: radius
spacing: 4
RowLayout {
id: ueTextLayout
Text {
id: ueStaffLoginText
text: qsTr("Staff Login")
verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignHCenter
font.family: "Padauk"
textFormat: Text.RichText
font.pointSize: 16
font.bold: true
color: ueKeypad.border.color
Layout.fillWidth: true
} // ueStaffLoginText
} // ueTextLayout
RowLayout {
id: uePeopleViewLayout
ListView {
id: uePeopleView
keyNavigationWraps: true
spacing: 4
antialiasing: true
model: uePeopleModel
Layout.fillWidth: true
Layout.fillHeight: false
//Layout.minimumWidth: 64
Layout.minimumHeight: 64
//Layout.preferredWidth: 96
Layout.preferredHeight: 96
//Layout.maximumWidth: 128
Layout.maximumHeight: 128
orientation: ListView.Horizontal
layoutDirection: Qt.LeftToRight
snapMode: ListView.SnapToItem
highlightRangeMode: ListView.ApplyRange
Component.onCompleted: {
var newIndex=(count%2==0)?(count/2):(Math.round(count/2));
positionViewAtIndex(newIndex, ListView.Center);
currentIndex=newIndex;
print(newIndex)
} // onCompleted - center items
delegate: Rectangle {
id: uePersonDelegate
width: 32
height: 32
ColumnLayout {
id: uePersonDelegateMainLayout
anchors.fill: parent
anchors.margins: radius
RowLayout {
id: uePersonDelegateImageLayout
Image {
id: uePersonImage
antialiasing: true
fillMode: Image.PreserveAspectFit
source: "image://uePeopleModel/"+model.ueRoleImage
} // uePersonImage
} // uePersonDelegateImageLayout
RowLayout {
id: uePersonDelegateNameLayout
Text {
id: ueTextPersonName
color: "#ffffff"
text: model.ueRoleName
font.bold: true
font.pixelSize: 16
verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignHCenter
} // ueTextPersonName
} // uePersonDelegateNameLayout
} // uePersonDelegateMainLayout
} // uePersonDelegate
add: Transition {
NumberAnimation {
property: "opacity";
from: 0;
to: 1.0;
duration: 100
} // NumberAnimation
NumberAnimation {
property: "scale";
from: 0;
to: 1.0;
duration: 100
} // NumberAnimation
} // Transition
displaced: Transition {
NumberAnimation {
properties: "x,y";
duration: 100;
easing.type: Easing.OutBounce
} // NumberAnimation
} // Transition
} // uePeopleView
} // uePeopleViewLayout
RowLayout {
id: ueTumblerLayout
Tumbler {
id: ueLoginKeypadTumbler
Layout.fillWidth: true
Layout.fillHeight: false
height: 100
antialiasing: true
TumblerColumn {
id: ueNumericTumblerColumnDigit1000
model: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
} // ueNumericTumblerColumnDigit1000
TumblerColumn {
id: ueNumericTumblerColumnDigit100
model: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
} // ueNumericTumblerColumnDigit100
TumblerColumn {
id: ueNumericTumblerColumnDigit10
model: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
} // ueNumericTumblerColumnDigit10
TumblerColumn {
id: ueNumericTumblerColumnDigit1
model: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
} // ueNumericTumblerColumnDigit1
} // ueLoginKeypadTumbler
} // ueTumblerLayout
RowLayout {
id: ueButtonsLayout
Button {
id: ueButtonLogin
Layout.fillWidth: true
text: qsTr("Login")
} // ueButtonLogin
Button {
id: ueButtonClear
Layout.fillWidth: true
text: qsTr("Clear")
} // ueButtonClear
Button {
id: ueButtonQuitApp
Layout.fillWidth: true
text: qsTr("Quit")
} // ueButtonQuitApp
} // ueButtonsLayout
} // ueMainColumnLayout
states: [
State {
name: "ueStateLoginOk"
PropertyChanges {
target: ueKeypad
border.color: "#00ff00"
}
PropertyChanges {
target: ueLoginText
color: "#00ff00"
}
}, // ueStateLoginOk
State {
name: "ueStateLoginOkFailed"
PropertyChanges {
target: ueKeypad
border.color: "#ff0000"
}
PropertyChanges {
target: ueLoginText
color: "#ff0000"
}
} // ueStateLoginOkFailed
] // states
} // ueKeypad
Сейчас, print(newIndex)
заявление выдает правильное значение 3
(в моем случае, так как на данный момент у меня есть 5 пунктов), и я бы хотел, чтобы третий элемент находился в центре ListView
и два других предмета слева и справа. Это возможно? И выходит за рамки этого вопроса, почему Transition
s также не работает, взятый из примера?
Я также установил highlightRangeMode: ListView.ApplyRange
взят из комментария подсказка.
Вот скриншот проблемы:
1 ответ
Проблема в том, что вы пытаетесь разместить ListView
делегаты в соответствии с вашими потребностями. Это совершенно неправильно, так как ListView
(так же, как все другие взгляды) предназначен для вас, в соответствии с ListView
размер ListView
всегда будет использовать все доступное пространство, в результате чего все делегаты будут располагаться слева, как вы уже видели.
Вместо того, чтобы навязывать поведение делегатам, вы должны ограничить ListView
размер и положение его, чтобы быть в центре. Затем вы можете использовать highlightRangeMode
с preferredHighlightBegin
а также preferredHighlightEnd
из этого ответа, чтобы убедиться, что в настоящее время выбран Item
находится в центре списка. Кроме того, используя StrictlyEnforceRange
, вы можете заставить выбранный Item
всегда оставаться в центре, что приведет к тому, что ИМО сможет лучше выбрать желаемое Item
,
Вот пример реализации этого подхода. Размеры жестко запрограммированы для простоты, но могут быть легко параметризованы. Как я уже сказал, я пошел немного дальше, установив политику выделения. Надеюсь, поможет.
import QtQuick 2.4
import QtQuick.Window 2.2
import QtQuick.Layouts 1.1
Window {
id: win
width: 300
height: 300
visible: true
ColumnLayout {
anchors.fill: parent
Rectangle {
Layout.fillWidth: true
Layout.fillHeight: true
color: "blue"
}
ListView {
Layout.alignment: Qt.AlignCenter
Layout.minimumWidth: 30 * 5 + 40
Layout.preferredHeight: 50
clip: true
spacing: 15
model: 10
orientation: ListView.Horizontal
delegate: Item {
width: 30
height: 50
Rectangle{
anchors.centerIn: parent
color: parent.ListView.isCurrentItem ? "red" : "steelblue"
width: 30
height: 30
Text {
text: index
anchors.centerIn: parent
}
scale: parent.ListView.isCurrentItem ? 1.5 : 1
Behavior on scale { NumberAnimation { duration: 200 } }
}
}
preferredHighlightBegin: width / 2 - 15
preferredHighlightEnd: width / 2 + 15
highlightRangeMode: ListView.StrictlyEnforceRange
Component.onCompleted: currentIndex = count / 2
}
Rectangle {
Layout.fillWidth: true
Layout.fillHeight: true
color: "yellow"
}
}
}