Qt QML ListView方法positionViewAtEnd()的作用正好相反
我快疯了。我在ScrollView中有一个ListView,与继承QabStretchListModel的模型连接。将对象添加到模型时,ListView将使用委托显示这些对象。到目前为止,一切顺利 但我真的希望视图保持滚动到底部(就像聊天窗口),我很难做到这一点。以下是相关的QML代码:Qt QML ListView方法positionViewAtEnd()的作用正好相反,qt,listview,qml,qt5.3,Qt,Listview,Qml,Qt5.3,我快疯了。我在ScrollView中有一个ListView,与继承QabStretchListModel的模型连接。将对象添加到模型时,ListView将使用委托显示这些对象。到目前为止,一切顺利 但我真的希望视图保持滚动到底部(就像聊天窗口),我很难做到这一点。以下是相关的QML代码: Rectangle { ScrollView { [anchor stuff] ListView { id: messageList
Rectangle {
ScrollView {
[anchor stuff]
ListView {
id: messageList
model: textMessageFiltered
delegate: messageDelegate
}
}
TextField {
id: messageEditor
[anchor stuff]
onAccepted: {
controller.sendTextMessage(text)
text = ""
/* This works. */
//messageList.positionViewAtEnd();
}
}
Component {
id: messageDelegate
Rectangle {
anchors.left: parent.left
anchors.right: parent.right
color: "white"
height: nameText.height + 4
Text {
id: nameText
wrapMode: Text.Wrap
text: "<b>" + authorName + " (" + authorId + ")</b> " + message
[anchor stuff]
}
ListView.onAdd: {
console.log("This prints just fine!")
messageList.positionViewAtEnd()
}
}
}
}
文本“此打印正确”打印,为什么不定位?事实上,它似乎将位置重置为顶部。因此,我尝试了位置视图开始()
,但效果相同
我完全被难住了。这感觉像一个bug。中有一个注释:
注意:方法只能在组件完成后调用。要在启动时定位视图,Component.onCompleted应调用此方法
将您的ListView.onAdd:
更改为
Component.onCompleted: {
console.log("This prints just fine!")
messageList.positionViewAtEnd()
}
而且效果很好
在您的情况下,ListView在创建和完成新委托之前发出
add
信号。ListView仍在幕后处理某些内容,因此positionViewAtEnd
无法按预期工作。而且,/*这很有效*/代码>因为它是在新委托完成后调用的。但是,不要认为这总是有效的。只需按照说明,在文档中的组件中调用positionViewAtEnd
。onCompleted
。您还需要设置当前索引
testme.qml
import QtQuick 2.2
import QtQuick.Controls 1.1
import QtQuick.Window 2.0
ApplicationWindow {
title: qsTr("Hello World")
width: 300
height: 240
ScrollView {
anchors.fill: parent
ListView {
anchors.fill: parent
id: messageList
model: messageModel
delegate: Text { text: mytextrole }
highlight: Rectangle { color: "red" }
highlightMoveDuration: 0
onCountChanged: {
var newIndex = count - 1 // last index
positionViewAtEnd()
currentIndex = newIndex
}
}
}
ListModel {
id: messageModel
ListElement { mytextrole: "Dog"; }
ListElement { mytextrole: "Cat"; }
}
Timer {
property int counter: 0
running: true
interval: 500
repeat: true
onTriggered: {
messageModel.append({"mytextrole": "Line" + (counter++)})
}
}
}
仍然会有一些跳到第一个元素,然后再跳下来几秒钟。你是对的。非常感谢。对于未来的谷歌用户来说,第二个重要部分是组件.onCompleted
必须出现在代理中,而不是列表本身。我错过了。嗯……你说得对。当您滚动列表时,ListView确实会创建新代理,而我的回答失败。也许您可以在调用positionViewAtEnd
之前检查模型中的元素数量,但我认为这不是一个好的解决方案。不清楚为什么/是否Qt开发人员真的打算将完成的
附加到委托上。似乎我们缺少了positionViewAtEnd
的预期用途。现在,我将撤消接受此答案。组件.onCompleted
信号可用于所有QML组件,例如您的矩形
。无论在何处创建了矩形
,在静态QML代码中或在委托中按需创建,它都可用。positionviewated
的文档可能有点误导。他们说的是:当列表被完全创建时,向下滚动(每个列表一次,启动时)。你的注释掉的解决方案有什么问题?这对我在Ubuntu上使用Qt5.4是有效的(从我所看到的情况来看,它位于末尾,而不是计数-2)。请为滚动和onCountChanged不工作时发生的挂起创建错误报告。问题是该项目没有立即添加到列表中(实际项目是从服务器请求添加的),因此它要么被一个(在发件人上)关闭,要么根本不更新(在另一个客户端上)。positionViewatStart()
必须对正在更新的列表本身起作用。我提交了一个错误请求(QTBUG-41571),所以我希望这篇文章足以澄清这个问题。你解决了这个问题吗?我有确切的问题,我找不到任何解决办法。谢谢!不幸的是,没有。我最终通过重新设计GUI解决了这个问题。我希望这个问题能在5.5中解决,但我还没有检查。如果你明白了,回来吧!:)有趣。也许这就是Qt中错误的来源。谢谢你节省了我的时间。
import QtQuick 2.2
import QtQuick.Controls 1.1
import QtQuick.Window 2.0
ApplicationWindow {
title: qsTr("Hello World")
width: 300
height: 240
ScrollView {
anchors.fill: parent
ListView {
anchors.fill: parent
id: messageList
model: messageModel
delegate: Text { text: mytextrole }
highlight: Rectangle { color: "red" }
highlightMoveDuration: 0
onCountChanged: {
var newIndex = count - 1 // last index
positionViewAtEnd()
currentIndex = newIndex
}
}
}
ListModel {
id: messageModel
ListElement { mytextrole: "Dog"; }
ListElement { mytextrole: "Cat"; }
}
Timer {
property int counter: 0
running: true
interval: 500
repeat: true
onTriggered: {
messageModel.append({"mytextrole": "Line" + (counter++)})
}
}
}