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. Display image in qml using Image provider.

Display image in qml using Image provider.

Scheduled Pinned Locked Moved Unsolved QML and Qt Quick
7 Posts 3 Posters 1.7k 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.
  • P Offline
    P Offline
    Pooja Bhusare
    wrote on 2 Feb 2021, 13:14 last edited by
    #1

    have created one application in that I want to received image from socket. Once it is received, it should display in QMl. 1:I am able to received Image from socket and display in QMl using image provider. But when I am trying to integrate this things on another application facing the following error :
    QML QQuickItem: Cannot anchor a horizontal edge to a vertical edge. QML Connections: Cannot assign to non-existent property "onNewFrameReceived" ReferenceError: imageprovider is not defined.

    main.cpp:
    QQmlApplicationEngine  engine;
          const QUrl url(QStringLiteral("qrc:/qml/main.qml"));
         engine.addImageProvider(QLatin1String("imageprovider"),
                                  new QmlImageProvider());
          QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
                           &app, [url](QObject *obj, const QUrl &objUrl) {
              if (!obj && url == objUrl)
                  QCoreApplication::exit(-1);
          }, Qt::QueuedConnection);
          engine.load(url);
    
    In this file I have created one window and trying to load the other file name as qml_view.qml and here I am displaying one background image.
    
    qml_view.qml:
    In this file i have divided into 3 parts. left container and right container and center container I want to show the image on center part of background image. I have created 1 button once that button press image received from socket should display.
    Item {
            id: name
            x: 25
            y: 34
            width: parent.width
            height: parent.height
            MouseArea {
                    id: progressArea
                    anchors.fill: progressBackground
                    onClicked:
                    {
                        image.source = "image://imageprovider/cover"
                    }
                }
            }
            Image {
                id: image
                anchors.left: text.right
                source: ""
                cache: false
                function reload() {
                    var oldSource = source;
                    source = "";
                    source = oldSource;
                    console.log("reload")
                }
            }
        }
    }
    
    
    1 Reply Last reply
    0
    • D Online
      D Online
      dheerendra
      Qt Champions 2022
      wrote on 2 Feb 2021, 17:20 last edited by
      #2

      You must be doing two mistakes

      1. Wrong anchor line assignments
      2. signal(framerecevd) specified may not exist in the component. There may be spelling mistake as well.

      If you provide good working example, we can help. Above code does not show any of the problem you mentioned.

      Dheerendra
      @Community Service
      Certified Qt Specialist
      http://www.pthinks.com

      1 Reply Last reply
      0
      • F Offline
        F Offline
        fcarney
        wrote on 2 Feb 2021, 18:36 last edited by
        #3

        @Pooja-Bhusare said in Display image in qml using Image provider.:

        engine.addImageProvider(QLatin1String("imageprovider"),
        new QmlImageProvider());

        What is a QmlImageProvider()?

        https://doc.qt.io/qt-5/qquickimageprovider.html

        C++ is a perfectly valid school of magic.

        P 1 Reply Last reply 3 Feb 2021, 05:35
        0
        • P Offline
          P Offline
          Pooja Bhusare
          wrote on 3 Feb 2021, 05:15 last edited by
          #4

          @dheerendra
          sorry I cant share entire code but i will try to share some function

          1 Reply Last reply
          0
          • F fcarney
            2 Feb 2021, 18:36

            @Pooja-Bhusare said in Display image in qml using Image provider.:

            engine.addImageProvider(QLatin1String("imageprovider"),
            new QmlImageProvider());

            What is a QmlImageProvider()?

            https://doc.qt.io/qt-5/qquickimageprovider.html

            P Offline
            P Offline
            Pooja Bhusare
            wrote on 3 Feb 2021, 05:35 last edited by
            #5

            @fcarney QmlImageProvider is my class name

            1 Reply Last reply
            0
            • P Offline
              P Offline
              Pooja Bhusare
              wrote on 3 Feb 2021, 05:45 last edited by
              #6
              main.cpp 
                int main(int argc, char *argv[])
              {
                  QGuiApplication app(argc, argv);
                  QFontDatabase::addApplicationFont(":/fonts/DejaVuSans.ttf");
                  app.setFont(QFont("DejaVu Sans"));
                  cluster=Cluster::instance();
                  QQmlApplicationEngine  engine;
                  QQmlContext *context = new QQmlContext(engine.rootContext());
                 engine.addImageProvider(QLatin1String("imageprovider"),
                                         new QmlImageProvider());
                 const QUrl url(QStringLiteral("qrc:/qml/main.qml"));
                 engine.rootContext()->setContextProperty("Cluster",cluster);
                 engine.load(url);
                 return app.exec();
              }
              
              main.qml
              
              this is my main qml file here i am loading 1 background image and calling view.qml file
              Window {
                  width: 1024
                  height: 600
                 title: qsTrId("title")
                 visible: true
                  Image {
                      width: 1024
                      height: 600
                      source: "qrc:/src/bkg.jpg"
                      Loader {
                          width: 1024
                          height: 600
                          anchors.fill: parent
                          asynchronous: true
                          enabled: status == Loader.Ready
                          source: "view.qml"
                          visible: enabled
                      }
                  }
              }
              
              
              view.qml
              
              This is my view .qml file here i have created image and call button if i pressed on call i can able to see the contact list 
              but if i pressed on image button i cannot display image received through socket.
              
              
               Connections {
                          target: imageprovider
                          onNewFrameReceived: server_image.reload();
                      }
                      Image {
                          id:image_default
                          x: 214
                          y: 0
                          width: 60
                          height: 60
                          source: "qrc:/src/Image-default.png"
                          opacity: 0.5
                          MouseArea{
                              id : imagearea
                              anchors.fill: parent
                              onClicked: {
              
                                   console.log("In mouse area image loader  function");
              
                                  if(call_default.opacity ===1 ){
                                      image_default.source="qrc:/src/Image-active.png"
                                     call_default.opacity = 0.5
                                      call_default.source = "qrc:/src/phone-default.png"
                                     }
                                  else {
                                      console.log("In else part   function");
              
                                      image_default.source= "qrc:/src/Image-active.png"
                                         }
                                              image_default.z = 1
                                              call_default.z = 0
                                              image_default.opacity =1
                                              backbutton.visible = true
                                         // server_image.source="image://imageprovider/cover"
              
                              }
                          }
                      Image {
                          id: server_image
                          x: 137
                          y: 280
                          width: 190
                          height: 130
                          source: ""
                          cache: false
                          function reload() {
                              var oldSource = source;
                              source =""
                              source = oldSource;
                              console.log("reload")
                          }
                      }
              }
              
              
              tcpserver.h
              class MyTcpServer : public QObject
              {
               Q_OBJECT
              public:
              
                  explicit MyTcpServer(QObject *parent = 0);
              signals:
                  void valueChanged(int newValue);
                  void newImageReceived(QImage);
              public slots:
                  void newConnection();
                  void on_readyRead();
              private:
                  QTcpServer *server;
                  int m_value;
              };
              
              #endif // MYTCPSERVER_H
              
              qmlimageprovider.h
              class QmlImageProvider : public QQuickImageProvider ,public QObject
              {
              public:
                  QmlImageProvider();
                  QImage requestImage(const QString &id, QSize *size, const QSize &requestedSize) override;
              public slots:
                  void updateImage(QImage new_image);
              
              private:
                  QImage server_image;
                  MyTcpServer *m;
              };
              
              qmlimageprovider.cpp
              
              MyTcpServer::MyTcpServer(QObject *parent) :
                  QObject(parent)
              {
                  server = new QTcpServer(this);
                  connect(server, SIGNAL(newConnection()),
                          this, SLOT(newConnection()));
                  connect(server,SIGNAL(readyRead()),this,SLOT(readyRead()));
                  if(!server->listen(QHostAddress::Any, 9999))
                  {
                      qDebug() << "Server could not start";
                  }
                  else
                  {
                      qDebug() << "Server started!";
                  }
              }
              
              void MyTcpServer::newConnection()
              {
                  QTcpSocket *socket = server->nextPendingConnection();
                  if(socket)
                  {
                      connect(socket ,SIGNAL(readyRead()),this,SLOT(on_readyRead()));
                      socket->flush();
                      socket->waitForBytesWritten(3000);
                  }
              }
              void MyTcpServer::on_readyRead()
              {
                  QTcpSocket * server = dynamic_cast<QTcpSocket*>(sender());
                  if(server)
                  {
                      //read data from socket
                      array.append(server->readAll());
                      if(array.size()<230400)
                      {
                          qDebug()<<"Array size " << array.size() ;
                      }
              
                      else {
                          //read an image
                          cv::Size const frame_size(240,320);
                          img = cv::Mat(240,320, CV_8UC3,array.data());
                          cv::waitKey(5000);
                          imdisplay=QImage ((uchar*)img.data, img.cols, img.rows, img.step, QImage::Format_RGB888);
                          emit newImageReceived(imdisplay);
                      }
                  }
              }
              QmlImageProvider::QmlImageProvider()
                  : QQuickImageProvider(QQuickImageProvider::Image)
              {
                  m = new MyTcpServer();
                  connect(m, &MyTcpServer::newImageReceived, this, &QmlImageProvider::updateImage);
                  m->newConnection();
              }
              
              QImage QmlImageProvider::requestImage(const QString &id, QSize *size, const QSize &requestedSize)
              {
                 return server_image;
              }
              void QmlImageProvider::updateImage(QImage new_image)
              {
                  server_image = new_image;
              }
              
              
              1 Reply Last reply
              0
              • F Offline
                F Offline
                fcarney
                wrote on 3 Feb 2021, 16:40 last edited by
                #7

                @Pooja-Bhusare said in Display image in qml using Image provider.:

                QQmlContext *context = new QQmlContext(engine.rootContext());

                Why are you doing this? Don't do this. You don't need a separate context.

                        Connections {
                            target: imageprovider
                            onNewFrameReceived: server_image.reload();
                        }
                

                imageprovider isn't a context property and doesn't need to be one.

                onNewFrameReceived isn't a signal of your image provider class.

                Why are you commenting this out?:
                server_image.source="image://imageprovider/cover"

                QImage QmlImageProvider::requestImage(const QString &id, QSize *size, const QSize &requestedSize)
                {
                   return server_image;
                }
                I going to return the same image regardless of your image://imageprovider/<value>.  Use "id" to differentiate.  This is fine if this is what you want.
                
                I don't know the networking side very well.  I have used image providers a lot.  
                

                You might need to do this when your image updates. I am not sure if the image provider will signal a change in the image.

                server_image.source=""
                server_image.source="image://imageprovider/cover"
                

                This will force the update the image if it changed. I have had to do this.

                C++ is a perfectly valid school of magic.

                1 Reply Last reply
                0

                1/7

                2 Feb 2021, 13:14

                • Login

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