Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. [Solved] Send QImage from C++ to QML via QQuickImageProvider or using a signal

[Solved] Send QImage from C++ to QML via QQuickImageProvider or using a signal

Scheduled Pinned Locked Moved QML and Qt Quick
5 Posts 4 Posters 11.6k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • M Offline
    M Offline
    MartynW
    wrote on last edited by
    #1

    My C++ class receives signals that carry a QImage and I wish to update a corresponding QML image.

    The QQuickImageProvider seems unsuitable as it only allows the QML to pull the image across. So maybe I need to forward the signal to QML, but I'm not clear how to pass the image across. Is this documented anywhere please?

    Thanks.

    1 Reply Last reply
    0
    • M Offline
      M Offline
      minimoog77
      wrote on last edited by
      #2

      One approach is to send signal to QML and then invoke na Image which will invoke your's QQuickImageProvider.

      Other is to implement your custom QML item implemented in C++ using scene graph API or maybe QQuickPaintedItem.

      1 Reply Last reply
      0
      • O Offline
        O Offline
        onek24
        wrote on last edited by
        #3

        Hello,

        i also tried to pass an QImage to QML using a model. He receives the image and also detects it as a QImage but can't handle it, well at least the Image-component can't. You'll have to provide a source for it, that means using the QQuickImageProvider.

        Please see this thread for more informations: "Passing QImage to QML":http://qt-project.org/forums/viewthread/37485

        Answer from digia:

        bq. As Image requires url, you cannot directly specify QImage for it. One
        option would be to change the QImage to QString and then use the QString as image source. So add images to resource file and use in cpp:
        Constructor:
        @Animal(const QString &type, const QString &size, const QString &image);@
        Adding an animal:
        @model.addAnimal(Animal("Wolf", "Medium", "my_image.png")@
        and then in qml:
        @ListView {
        width: 200; height: 250

        model: myModel
        
        Component {
             id: modelDelegate
             Item {
                 width: 180; height: 40
                 Row {
                     Text { text: "Animal: " + type + ", " + size }
                     Image {source: image}
                 }
             }
         }
        
        delegate: modelDelegate
        

        }@
        Another option would be to use QQuickImageProvider class.
        http://qt-project.org/doc/qt-5.0/qtquick/qquickimageprovider.html
        An example of how to use QQuickImageProvider can be found from:
        \qtdeclarative\examples\quick\imageprovider

        1 Reply Last reply
        0
        • M Offline
          M Offline
          MartynW
          wrote on last edited by
          #4

          Thanks for your suggestions guys. I had thought about a signal then a getImage via a provider, but wasn't clear how to refresh with a new image for the same id. That link suggested how to overcome that, but then I realized I needed a frame number as the id and everything would then work. And it does!

          The scene graph API is an interesting idea but a bit out of my comfort zone at the moment so that was my fallback which I didn't need in the end.

          This is what I ended up with, it seems quite neat and compact really. Good old Qt.

          main.cpp
          @#include <QtGui/QGuiApplication>
          #include <QQmlContext>
          #include <QTimer>
          #include "qtquick2applicationviewer.h"
          #include "NwImageProvider.h"

          int main(int argc, char *argv[])
          {
          QGuiApplication app(argc, argv);
          QTimer timer;
          NwImageProvider *imageProvider = new NwImageProvider;
          QtQuick2ApplicationViewer viewer;

          viewer.rootContext()->engine()->addImageProvider(QLatin1String("NwImageProvider"), imageProvider);
          viewer.rootContext()->setContextProperty("NwImageProvider", imageProvider);
          viewer.setMainQmlFile&#40;QStringLiteral("qml/ImageToQml/main.qml"&#41;);
          viewer.showExpanded();
          
          QObject::connect(&timer, SIGNAL(timeout()), imageProvider, SLOT(slotNewFrameReady()));
          timer.setInterval(1000);
          timer.setSingleShot(false);
          timer.start();
          
          return app.exec();
          

          }@

          main.qml
          @import QtQuick 2.1
          import QtQuick.Controls 1.0

          Rectangle {
          width: 360
          height: 360
          property bool isRedTop: false
          property int currentFrameNumber: 0

          Column {
              anchors.centerIn: parent
              Image { source: "image://NwImageProvider/" + currentFrameNumber}
              Image { source: "image://NwImageProvider/" + (currentFrameNumber + 1)}
          }
          
          Connections {
              target: NwImageProvider
              onSignalNewFrameReady: {
                  console.log("onSignalNewFrameReady", frameNumber);
                  currentFrameNumber = frameNumber;
              }
          }
          

          }
          @

          NwImageProvider.h
          @#include <QObject>
          #include <QQuickImageProvider>

          class NwImageProvider : public QObject, public QQuickImageProvider
          {
          Q_OBJECT
          public:
          NwImageProvider();
          QImage requestImage(const QString &id, QSize *size, const QSize &requestedSize);

          public slots:
          void slotNewFrameReady();

          signals:
          Q_SIGNAL void signalNewFrameReady(int frameNumber);

          };
          @

          NwImageProvider.cpp
          @#include "NwImageProvider.h"

          NwImageProvider::NwImageProvider()
          : QQuickImageProvider(QQmlImageProviderBase::Image)
          {
          }

          QImage NwImageProvider::requestImage(const QString &id, QSize *size, const QSize &requestedSize)
          {
          int width = 100;
          int height = 50;
          int requestNumber;
          QString strId = id;
          bool bIsOk;

          this->blockSignals(true);   // To allow debugging
          
          requestNumber = strId.toInt(&bIsOk);
          if (bIsOk)
          {
              switch (requestNumber % 4)
              {
              case 0: strId = "yellow"; break;
              case 1: strId = "red"; break;
              case 2: strId = "green"; break;
              case 3: strId = "blue"; break;
              default: strId = "black"; break;
              }
          }
          if (size)
              *size = QSize(width, height);
          QImage image(requestedSize.width() > 0 ? requestedSize.width() : width,
                         requestedSize.height() > 0 ? requestedSize.height() : height, QImage::Format_RGB32);
          image.fill(QColor(strId).rgba());
          
          this->blockSignals(false);
          
          return image;
          

          }

          void NwImageProvider::slotNewFrameReady()
          {
          static int nextFrameNumber = 0;
          emit signalNewFrameReady(nextFrameNumber++);
          }
          @

          1 Reply Last reply
          0
          • L Offline
            L Offline
            lygstate
            wrote on last edited by
            #5

            great answer, I am looking for it.

            1 Reply Last reply
            0

            • Login

            • Login or register to search.
            • First post
              Last post
            0
            • Categories
            • Recent
            • Tags
            • Popular
            • Users
            • Groups
            • Search
            • Get Qt Extensions
            • Unsolved