Man*_*elH 5 qt listview qt4 qml qt5
将QML ListView元素与其section属性结合使用时,我遇到了一个非常具体的问题.
我使用的是Qt 4.8.6,但是当我在Qt 5.3.1中尝试这个时,我也有同样的问题.
通过简单地将import语句更改为,也可以在旧版本的Qt中运行以下代码
导入QtQuick 1.0(<Qt 4.7.4)
要么
import QtQuick 1.1(For = = Qt 4.7.4)
这是一个独立的用例来演示我的问题:
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
}
}
}
Run Code Online (Sandbox Code Playgroud)
我使用ListView显示动物模型列表,按其大小分类.为了在视图中实现这种分类,我使用上面给出的代码中实现的ListView 的section.property,section.critiria和section.delegate属性.
(注意:请忽略我提供给ListView的模型没有排序的事实,我知道这将在ListView中创建许多重复的类别条目.这不是重点.)
当模型的数量超过ListView的可见区域时,我使用属性totalPages来计算有多少完整的ListView页面用于导航.向上箭头和向下箭头按钮分别按ListView的高度递减和递增ListView 的content.Y.
问题是ListView 的contentHeight不会保持静态,它会动态更改并导致我的totalPages属性计算不正确.
有趣的是,当且仅当我为sectionHeaderDelegate矩形设置高度时才会出现这种情况.如果我注释掉高度语句(高度:50),ListView 的contentHeight保持静态,如预期的那样 - 缺点是节标题/类别现在位于模型文本之上,这根本没用.
所以我的问题是,为什么QML ListView元素的contentHeight会动态地改变当且仅当我使用高度已设置为非零值的节委托时?
另外,我在ListView中留下了以下属性用于测试目的,ListView应该与向上/向下箭头一起使用:
Run Code Online (Sandbox Code Playgroud)interactive: true flickableDirection: Flickable.VerticalFlick boundsBehavior: Flickable.StopAtBounds
我知道这很古老,但无论如何我都会在这里回答它,因为我正在寻找解决方案;
如果您的物品的高度是固定的,则可以通过简单地通过公式设置值来动态设置容器的高度:
MyContainerWithListItems {
height: MyModel.items.length * height
}
Run Code Online (Sandbox Code Playgroud)
如果你有可变高度的物品,那就会更困难;解决方案可能是让 onChange 事件触发一个函数,该函数会爬行您的项目并手动添加高度。