之前在开发网格视图相关功能,qml使用了GridView作为视图,而model则通过C++ QAbstractItemModel实现再绑定到GridView。因为在项目中要定时更新数据并根据数据去过更新视图,所以使用了定时器去调用beginResetModel()和endResetModel()这对组合函数。但是每次调用这对函数,视图(view)显示位置会重置到顶部,这与预期不一样,因为我希望是数据被更新,但视图的位置不能被改变。
因此我去查阅了qt助手,beginResetModel()函数调用后,会重置任何依附在此模型上的视图,因此视图的contentY属性也会被重置。
想到这个问题,我就有了解决思路,既然是contentY被重置为0了,那么我能不能保持contentY的值不变呢?答案是可以的。
首先我们知道,在调用beginResetModel函数时,会发送modelAboutToBeReset信号,调用endResetModel时,会调用modelReset信号,那么我们就可以在我们的视图(view)里面,通过监听这两个信号,在监听到modelAboutToBeReset信号时,先记录下contentY的值,在监听到modelReset信号时,重置一下contentY。
GridView{
property int conY: 0 //用于记录上次视图停留的位置
.......................
Component.onCompleted:{
model.modelAboutToBeReset.connect(onStartReset)
model.modelReset.connect(onEndReset)
}
function onStartReset(){
conY = contentY
}
function onEndReset(){
contentY = conY
}
}
尝试过之后,视图不会再跳到顶部,问题解决。
问题补充,这个方法在qt5.15.2使用是没有问题的,但是当我将版本升级到qt6.7,发现还是会重新回到顶部,但contentY的值是有改变的,后续如果有解决方法将会进行更新。