Qt Forum

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Unsolved

    Unsolved Display image in qml using Image provider.

    QML and Qt Quick
    3
    7
    529
    Loading More Posts
    • 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
      Pooja Bhusare last edited by

      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 Reply Quote 0
      • dheerendra
        dheerendra Qt Champions 2022 last edited by

        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 Reply Quote 0
        • fcarney
          fcarney last edited by

          @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 Reply Quote 0
          • P
            Pooja Bhusare last edited by

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

            1 Reply Last reply Reply Quote 0
            • P
              Pooja Bhusare @fcarney last edited by

              @fcarney QmlImageProvider is my class name

              1 Reply Last reply Reply Quote 0
              • P
                Pooja Bhusare last edited by

                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 Reply Quote 0
                • fcarney
                  fcarney last edited by

                  @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 Reply Quote 0
                  • First post
                    Last post