简体   繁体   English

将元素附加到 ListModel 后如何更新 QML ListView?

[英]How to update QML ListView after appending an element into ListModel?

I have a ListView in my QML:我的 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
        }
    }
}

At first I add some items using an image provider and function addImage(src) :首先,我使用图像提供程序和函数addImage(src)添加一些项目:

QVariant qv(QString("image://plots/").append(imageName));
QMetaObject::invokeMethod(plotList, "addImage", Q_ARG(QVariant, qv));

Everything works fine, the ListView updates automatically.一切正常, ListView自动更新。 Then I clear all items from the ListModel and add some new ones:然后我清除ListModel所有项目并添加一些新项目:

QMetaObject::invokeMethod(plotList, "clear");
QVariant qv(QString("image://plots/").append(someNewImage));
QMetaObject::invokeMethod(plotList, "addImage", Q_ARG(QVariant, qv));

The ListView doesn't update even with something like:即使使用以下内容, ListView也不会更新:

QMetaObject::invokeMethod(plotList, "redraw");

So I have to scroll up and down several times to make old elements disappear and new ones appear, but anyway the first element of 20 remains the same, whatever I do.所以我必须上下滚动几次才能让旧元素消失而新元素出现,但无论如何,20 的第一个元素保持不变,无论我做什么。

What should I use in redraw() to force the ListView to update?我应该在redraw()使用什么来强制ListView更新? Maybe somehow emit a dataChanged signal of ListModel ?也许以某种方式发出ListModeldataChanged信号?

Thank you for your answers!谢谢您的回答! In my case the issue was in images' names.就我而言,问题出在图像名称上。 The names remained the same, and, though the image provider could provide new images by this names, the ListView didn't request the new images.名称保持不变,虽然图像提供者可以通过这个名称提供新图像,但 ListView 没有请求新图像。 So now I just change the names for every update.所以现在我只是为每次更新更改名称。

Well, you shouldn't need to do anything to get the correct behavior.好吧,您不需要做任何事情来获得正确的行为。 I suppose the problem has to do with doing things from C++ which happens in a blocking manner and doesn't give the objects the time for events to be processed.我想这个问题与从 C++ 做事情有关,它以阻塞方式发生,并且没有给对象处理事件的时间。

Try using a queued connection for invokeMethod() .尝试对invokeMethod()使用排队连接。

QMetaObject::invokeMethod(plotList, "addImage", Qt::QueuedConnection, Q_ARG(QVariant, qv));

However, accessing QML functions from C++ spells "bad design", you shouldn't really be doing that, QML should access C++, not vice versa.然而,从 C++ 访问 QML 函数拼写“糟糕的设计”,你真的不应该这样做,QML 应该访问 C++,反之亦然。 If you need to compose the actual strings in C++ that much, you can use a signal and emit the string with it, and connect it to QML handlers, this way you will interact with the model from QML.如果您需要在 C++ 中编写那么多实际字符串,您可以使用信号并用它发出字符串,并将其连接到 QML 处理程序,这样您将与 QML 中的模型进行交互。

This should be solved by setting the cache property of the QML Image to false.这应该通过将 QML Image 的缓存属性设置为 false 来解决。 From the Image caching section of http://doc.qt.io/qt-5/qquickimageprovider.html :http://doc.qt.io/qt-5/qquickimageprovider.html的图像缓存部分:

Images returned by a QQuickImageProvider are automatically cached, similar to any image loaded by the QML engine. QQuickImageProvider 返回的图像会自动缓存,类似于 QML 引擎加载的任何图像。 When an image with a "image://" prefix is loaded from cache, requestImage() and requestPixmap() will not be called for the relevant image provider.当从缓存中加载带有“image://”前缀的图像时,将不会为相关图像提供程序调用 requestImage() 和 requestPixmap()。 If an image should always be fetched from the image provider, and should not be cached at all, set the cache property to false for the relevant Image如果应该始终从图像提供者获取图像,并且根本不应该缓存图像,请将相关图像的缓存属性设置为 false

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM