Search code examples
qtqmlqtquick2qimageqtquickcontrols

Updating multiple QImages on QML::Image view displays only the last one sent


I have Image qml component to display QImages. Following is the QML code for it.

Code:

Item {

    Image {
       id: my_qimage_viewer
       anchors.fill: parent
    }

    Connections {
        target: qimage_selector_cpp_backend
        onQImageDisplayRequested: {
            my_qimage_viewer.source = next_qimage_source
            console.log("New qimage sent for display is : " + my_qimage_viewer.source)
        }
    }

}

What is working:
I have a C++ class using QQuickImageProvider to supply QImages with different IDs every time.

This technique basically works if I update single QImages on selection of some button by user. I can generate a QImage on the fly & update it on my_qimage_viewer. Also able to display multiple different images on demand from user. This proves that my technique using QQuickImageProvider is basically working.

What is not working
But, here is where the problem arises. when I send many QImages subsequently, like 50-60 of them all in a for loop, then it does not display all but only displays the last one sent for update !

My objective here is to try play 50-60 QImages with some millis gap in between to make them appear like a video/animation. Is it that the Image component is not made for such kind of use? Or is it that I am doing some mistake?

Question:
May be I should wait for each QImage to be display complete before updating the next? How can I do that if that is whats missing?

Is there an example of an app using Image to display multiple QImages making it appear like a video or animation?


Solution

  • if you use a for-loop you do not give time to show and update the images, you should give a little time between each image.

    Assuming that the acquisition time of the image is less than a certain value, for example less than 1/60 seconds we could use a NumberAnimation setting in an appropriate step:

    Window {
        visible: true
        width: 640
        height: 480
    
        Image {
            property int number
            id: name
            source: "image://numbers/"+number
    
            NumberAnimation on number {
                from:0
                to: 60
                duration: 1000
            }
        }
    }
    

    imageprovider.h

    #ifndef IMAGEPROVIDER_H
    #define IMAGEPROVIDER_H
    
    #include <QQuickImageProvider>
    #include <QPainter>
    #include <QTime>
    
    class ImageProvider : public QQuickImageProvider
    {
    public:
        ImageProvider():QQuickImageProvider(QQuickImageProvider::Image){
            qsrand(QTime::currentTime().msec());
        }
        QImage requestImage(const QString &id, QSize *size, const QSize &requestedSize){
            int width = 100;
            int height = 50;
            if (size)
                *size = QSize(width, height);
            QImage img(requestedSize.width() > 0 ? requestedSize.width() : width,
                   requestedSize.height() > 0 ? requestedSize.height() : height, QImage::Format_RGB32);
            img.fill(QColor(qrand() % 256, qrand() % 256, qrand() % 256));
            QPainter painter(&img);
            painter.setRenderHint(QPainter::Antialiasing, true);
            painter.drawText(QRectF(QPointF(0, 0), img.size()),  Qt::AlignCenter,
                             QTime::currentTime().toString("hh:mm:ss.z")+" "+id);
            painter.end();
            return img;
        }
    };
    
    #endif // IMAGEPROVIDER_H
    

    A complete example can be found in the following link