我的QML中有ListView
:
ListView {
id: listView1
width: parent.width
height: parent.height
interactive: true
clip: true
visible: true
property int elementH: 200
Component.onCompleted: {
mSingals.setPlotList(listView1);
}
function addImage(src) {
listModel.append({"imageSrc": src});
}
function clear() {
listModel.clear();
}
function redraw() {
// ?????
//listView1.update();
}
model: ListModel {
id: listModel
objectName: lModel
}
delegate: Rectangle {
id: delegateItem
width: listView1.width; height: listView1.elementH
color: "blue"
Image {
anchors.left: parent.left
source: imageSrc
visible: true
}
}
}
首先,我使用图像提供程序和函数addImage(src)
添加一些项目:
QVariant qv(QString("image://plots/").append(imageName));
QMetaObject::invokeMethod(plotList, "addImage", Q_ARG(QVariant, qv));
一切正常,ListView
会自动更新。
然后我清除ListModel
中的所有项目并添加一些新项目:
QMetaObject::invokeMethod(plotList, "clear");
QVariant qv(QString("image://plots/").append(someNewImage));
QMetaObject::invokeMethod(plotList, "addImage", Q_ARG(QVariant, qv));
ListView
即使使用以下内容也不会更新:
QMetaObject::invokeMethod(plotList, "redraw");
所以我必须多次向上和向下滚动以使旧元素消失并出现新元素,但无论如何,无论我做什么,20的第一个元素都保持不变。
我应该在redraw()
中使用什么来强制ListView
更新?
也许会以某种方式发出dataChanged
的{{1}}信号?
答案 0 :(得分:1)
感谢您的回答!在我的情况下,问题是图像的名称。名称保持不变,虽然图像提供者可以通过此名称提供新图像,但ListView不会请求新图像。所以现在我只需更改每次更新的名称。
答案 1 :(得分:0)
好吧,你不需要做任何事情来获得正确的行为。我认为这个问题与C ++中的事情有关,这是以阻塞方式发生的,并没有给对象提供处理事件的时间。
尝试使用invokeMethod()
的排队连接。
QMetaObject::invokeMethod(plotList, "addImage", Qt::QueuedConnection, Q_ARG(QVariant, qv));
然而,从C ++访问QML函数意味着“糟糕的设计”,你不应该这样做,QML应该访问C ++,反之亦然。如果你需要在C ++中组合实际的字符串那么多,你可以使用一个信号并用它发出字符串,并将它连接到QML处理程序,这样你就可以从QML与模型交互。
答案 2 :(得分:0)
这应该通过将QML Image的cache属性设置为false来解决。来自http://doc.qt.io/qt-5/qquickimageprovider.html的图片缓存部分:
QQuickImageProvider返回的图像会自动缓存,类似于QML引擎加载的任何图像。当从缓存加载带有“image://”前缀的图像时,不会为相关图像提供程序调用requestImage()和requestPixmap()。如果应始终从图像提供程序中提取图像,并且根本不应缓存该图像,请将相关图像的缓存属性设置为false