Qt QML ListView内容高度行为
当结合使用QML ListView元素及其部分属性时,我遇到了一个非常具体的问题 我正在使用Qt4.8.6,但在Qt5.3.1中尝试此功能时,我也遇到了同样的问题 以下代码也可以通过将import语句更改为 导入QtQuick 1.0(适用于Qt QML ListView内容高度行为,qt,listview,qt4,qml,qt5,Qt,Listview,Qt4,Qml,Qt5,当结合使用QML ListView元素及其部分属性时,我遇到了一个非常具体的问题 我正在使用Qt4.8.6,但在Qt5.3.1中尝试此功能时,我也遇到了同样的问题 以下代码也可以通过将import语句更改为 导入QtQuick 1.0(适用于=Qt 4.7.4) 下面是一个独立的用例来演示我的问题: import QtQuick 2.2 Rectangle { width: 800 height: 800 color: "black" property int
import QtQuick 2.2
Rectangle {
width: 800
height: 800
color: "black"
property int pageNumber: 1
property int totalPages: Math.ceil(animalListView.contentHeight/animalListView.height)
Text {
x: 2
y: 90
color: "Orange"
text: "Expected height: " + (animalListView.count*70 + (50*10))
font.pixelSize: 28
}
Text {
x: 2
y: 0
color: "Orange"
text: "Actual ContentHeight: " + animalListView.contentHeight
font.pixelSize: 28
}
Text {
x: 2
y: 30
color: "Orange"
text: "Actual ChildrenRectHeight: " + animalListView.childrenRect.height
font.pixelSize: 28
}
Text {
x: 2
y: 60
color: "Orange"
text: "Total model items (minus sections): " + animalListView.count
font.pixelSize: 28
}
Rectangle {
id: boundingRect
width: 640
height: 500
x: 20
y: 200
radius: 10
border.width: 1
border.color: "green"
color: "transparent"
// The delegate for each section header
Component {
id: sectionHeaderDelegate
Rectangle {
width: parent.width
height: 50 // this is the problem
color: "transparent"
Text {
anchors.left: parent.left
id: headerText
text: section
color: "red"
}
Rectangle {
anchors.fill: parent
border.color: "purple"
border.width: 1
color: "transparent"
}
}
}
ListModel {
id: animalsModel
ListElement { name: "1Parrot"; size: "Small" }
ListElement { name: "2Guinea pig"; size: "Small" }
ListElement { name: "3Dog"; size: "Medium" }
ListElement { name: "4Cat"; size: "Medium" }
ListElement { name: "5Elephant"; size: "Medium" }
ListElement { name: "6Parrot"; size: "Small" }
ListElement { name: "7Guinea pig"; size: "Small" }
ListElement { name: "8Dog"; size: "Medium" }
ListElement { name: "9Cat"; size: "Medium" }
ListElement { name: "10Elephant"; size: "Large" }
ListElement { name: "11Parrot"; size: "Large" }
ListElement { name: "12Guinea pig"; size: "Large" }
ListElement { name: "13Dog"; size: "Large" }
ListElement { name: "14Cat"; size: "Medium" }
ListElement { name: "15Elephant"; size: "Large" }
ListElement { name: "16Parrot"; size: "Small" }
ListElement { name: "17Guinea pig"; size: "Small" }
ListElement { name: "18Dog"; size: "Medium" }
ListElement { name: "19Cat"; size: "Medium" }
ListElement { name: "20Elephant"; size: "Large" }
}
ListView {
id: animalListView
anchors.fill: parent
anchors.margins: 10
clip: true
interactive: true
flickableDirection: Flickable.VerticalFlick
boundsBehavior: Flickable.StopAtBounds
model: animalsModel
delegate: Item {
width: parent.width
height: 70
Text {
text: name
color: "green"
}
Rectangle {
anchors.fill: parent
border.color: "yellow"
border.width: 1
color: "transparent"
}
}
section.property: "size"
section.criteria: ViewSection.FullString
section.delegate: sectionHeaderDelegate
}
}
Rectangle {
anchors.top: boundingRect.top
anchors.left: boundingRect.right
anchors.leftMargin: 20
width: 40
height: 40
color: "blue"
MouseArea {
anchors.fill: parent
onClicked: {
if (pageNumber > 1) {
animalListView.contentY -= animalListView.height;
animalListView.returnToBounds();
--pageNumber;
}
}
}
enabled: (!animalListView.atYBeginning)
visible: !(animalListView.atYBeginning && animalListView.atYEnd)
Text {
anchors.centerIn: parent
font.family: "Wingdings 3"
font.pixelSize: 40
text: "Ç" // Up arrow
}
}
Text {
visible: totalPages > 1
anchors.left: boundingRect.right
anchors.verticalCenter: boundingRect.verticalCenter
width: 100
height: 20
font.pixelSize: 18
horizontalAlignment: Text.AlignHCenter
color: "red"
text: qsTr("%1 of %2").arg(pageNumber).arg(totalPages)
}
Rectangle {
anchors.bottom: boundingRect.bottom
anchors.left: boundingRect.right
anchors.leftMargin: 20
width: 40
height: 40
color: "orange"
MouseArea {
anchors.fill: parent
onClicked: {
if (pageNumber < totalPages) {
animalListView.contentY += animalListView.height;
++pageNumber;
}
}
}
enabled: (!animalListView.atYEnd)
visible: !(animalListView.atYBeginning && animalListView.atYEnd)
Text {
anchors.centerIn: parent
font.family: "Wingdings 3"
font.pixelSize: 40
text: "È" // Down arrow
}
}
}
这是因为ListView通过当前可见的项来估计其内容高度。检查当您的分区无法分组时会发生什么情况。ListView避免实例化每个项目,因此它不知道不可见内容的适当大小 我知道这很古老,但我还是会在这里回答,因为我一直在寻找解决方案 如果您的项目具有固定高度,则只需通过以下公式设置值,即可动态设置容器的高度:
MyContainerWithListItems {
height: MyModel.items.length * height
}
如果你有可变高度的物品,那就更难了;解决方案可能是让onChange事件触发一个函数,该函数在项目中爬行并手动添加高度。声明一个全局属性,该属性存储listview的高度:
property int propertyListViewHeight:0
将ListView放置在高度等于该全局属性的透明项中propertyListViewHeight
:
Item {
id: rectangleEntities
width: parent.width
height: propertyListViewHeight
ListView {
id: listViewEntities
anchors.fill: parent
model: entityModel
delegate: listDelegate
focus: true
boundsBehavior: Flickable.StopAtBounds
highlightMoveDuration: 1000
highlightMoveVelocity: 1000
}
}
在代理定义中添加onCompleted信号,然后将列表中每个项目的高度添加到全局属性propertyListViewHeight
组成部分{
id:listDelegate
长方形{
id:集装箱
宽度:parent.width
Component.onCompleted: {
propertyListViewHeight += height
}
}
}
我从您链接到的线程中得到的结论是“当垂直列表视图中的项目没有固定高度时,将估计contentHeight。”好的,但在我的例子中,所有模型项都具有相同的隐式高度,并且节代理也具有固定高度。我没有对任何模型项或节代理使用可变高度,但我仍然存在动态更改contentHeight的相同问题。我的问题纯粹源于节代理的使用。设置e delegate对其隐式值以外的任何内容的高度都会导致计算/估计contentHeight的方式异常,即使该节委托具有固定高度!您的节标题具有动态高度,因为如果它是节组中的第一个项,则可以使用50像素的高度绘制;如果它不是组中的第一个项,则可以不绘制。正如我所说的看看当你的分区无法分组时会发生什么情况-每个固定大小的项目都有自己的固定大小分区标题,因此没有任何内容是动态的。你能提供一个图表,或者你想说的内容的一些可视化表示吗?我不太明白,抱歉:(
Component.onCompleted: {
propertyListViewHeight += height
}
}
}