Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. (QWebEngineView )Passing argument values ​​to js function and drawing on canvas
Forum Updated to NodeBB v4.3 + New Features

(QWebEngineView )Passing argument values ​​to js function and drawing on canvas

Scheduled Pinned Locked Moved Unsolved General and Desktop
7 Posts 3 Posters 454 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
    MyNameIsQt
    wrote on 20 Nov 2023, 07:31 last edited by MyNameIsQt
    #1

    I posted a question a while ago. I'm organizing it again and uploading it.
    The following function loads a binary image and sends it to html so that js can draw the image onto the canvas.
    I know that the OnDraw function has some problems internally. channel is declared as a local variable, which is not good. But I want to ignore it here.
    The problem is that the drawCanvas function in the js file does not work properly. This code does not draw an image, but rather receives the size of the image as a variable and displays that size on the canvas. However, as you can see in the picture below, only [object Event] is visible. The file size is passed into the drawCanvas function, but the canvas cannot update this value and only shows an [object Event]. What is the reason and how can I fix this?

    bool CBackground::onDraw()
    {
       if(!m_pBkgndImage->isNull()){
    
            if (m_pBkgndImage->colorSpace().isValid()){
                m_pBkgndImage->convertToColorSpace(QColorSpace::SRgb);
            }
    
            QPoint point(0,0);
            point.rx() = m_bkgndHeader.Left;
            point.ry() = m_bkgndHeader.Top;
    
            QWebChannel channel;
    
            QVariant imageVariant = QVariant::fromValue(*m_pBkgndImage);
    
            imageObject = new QObject();
            imageObject->setProperty("imageData", imageVariant);
    
            channel.registerObject("imageObject", imageObject);
    
            int imageSizeInBytes = m_pBkgndImage->bytesPerLine() * m_pBkgndImage->height();
    
            QByteArray imageDataArray(reinterpret_cast<const char*>(m_pBkgndImage->bits()), imageSizeInBytes);
    
            webView.page()->setWebChannel(&channel);
    
            //QString jsCode = QString("drawCanvas('%1');").arg(QString(imageDataArray.toBase64()));
            // file size
            QString jsCode = QString("drawCanvas('%1');").arg(imageDataArray.size());
    
            webView.page()->runJavaScript(jsCode);
    
            if(!m_pBkgndImage->isNull()){
                delete m_pBkgndImage;
                m_pBkgndImage = nullptr;
            }
    
            delete imageObject;
    
            return true;
    
        }
        return false;
    }
    
    // canvas.js
    function drawCanvas(imageData){
            imageData = imageData || "DefaultText"; 
            var canvas = document.getElementById("myCanvas");
            var context = canvas.getContext("2d");
    
            context.fillStyle = "yellow";
            context.fillRect(0, 0, canvas.width, canvas.height);
            context.font="48px serif";
            context.fillStyle = "black";
            console.error("Text "+imageData);
            context.fillText(imageData, 10, 50);
    
            if(imageData.length > 0 ){
                console.error("Image Data Length: " + (imageData ? imageData.length : "Undefined"));
            }
            /*
            var img = new Image();
            img.src = "data:image/webp;base64," + imageData;
    
            img.onerror = function(){
                console.error("Image failed to load");
            };
    
            img.onload = function() {
                context.drawImage(img, 0, 0);
            };
            */
        }
    

    44.JPG

    js: Uncaught ReferenceError: drawCanvas is not defined
    

    This error occurs in this part of the onDraw function.

    QString jsCode = QString("drawCanvas('%1');").arg(imageDataArray.size());
    

    I don't know how to resolve this error.

    캡처47.JPG

    J 1 Reply Last reply 20 Nov 2023, 07:36
    0
    • M MyNameIsQt
      20 Nov 2023, 07:31

      I posted a question a while ago. I'm organizing it again and uploading it.
      The following function loads a binary image and sends it to html so that js can draw the image onto the canvas.
      I know that the OnDraw function has some problems internally. channel is declared as a local variable, which is not good. But I want to ignore it here.
      The problem is that the drawCanvas function in the js file does not work properly. This code does not draw an image, but rather receives the size of the image as a variable and displays that size on the canvas. However, as you can see in the picture below, only [object Event] is visible. The file size is passed into the drawCanvas function, but the canvas cannot update this value and only shows an [object Event]. What is the reason and how can I fix this?

      bool CBackground::onDraw()
      {
         if(!m_pBkgndImage->isNull()){
      
              if (m_pBkgndImage->colorSpace().isValid()){
                  m_pBkgndImage->convertToColorSpace(QColorSpace::SRgb);
              }
      
              QPoint point(0,0);
              point.rx() = m_bkgndHeader.Left;
              point.ry() = m_bkgndHeader.Top;
      
              QWebChannel channel;
      
              QVariant imageVariant = QVariant::fromValue(*m_pBkgndImage);
      
              imageObject = new QObject();
              imageObject->setProperty("imageData", imageVariant);
      
              channel.registerObject("imageObject", imageObject);
      
              int imageSizeInBytes = m_pBkgndImage->bytesPerLine() * m_pBkgndImage->height();
      
              QByteArray imageDataArray(reinterpret_cast<const char*>(m_pBkgndImage->bits()), imageSizeInBytes);
      
              webView.page()->setWebChannel(&channel);
      
              //QString jsCode = QString("drawCanvas('%1');").arg(QString(imageDataArray.toBase64()));
              // file size
              QString jsCode = QString("drawCanvas('%1');").arg(imageDataArray.size());
      
              webView.page()->runJavaScript(jsCode);
      
              if(!m_pBkgndImage->isNull()){
                  delete m_pBkgndImage;
                  m_pBkgndImage = nullptr;
              }
      
              delete imageObject;
      
              return true;
      
          }
          return false;
      }
      
      // canvas.js
      function drawCanvas(imageData){
              imageData = imageData || "DefaultText"; 
              var canvas = document.getElementById("myCanvas");
              var context = canvas.getContext("2d");
      
              context.fillStyle = "yellow";
              context.fillRect(0, 0, canvas.width, canvas.height);
              context.font="48px serif";
              context.fillStyle = "black";
              console.error("Text "+imageData);
              context.fillText(imageData, 10, 50);
      
              if(imageData.length > 0 ){
                  console.error("Image Data Length: " + (imageData ? imageData.length : "Undefined"));
              }
              /*
              var img = new Image();
              img.src = "data:image/webp;base64," + imageData;
      
              img.onerror = function(){
                  console.error("Image failed to load");
              };
      
              img.onload = function() {
                  context.drawImage(img, 0, 0);
              };
              */
          }
      

      44.JPG

      js: Uncaught ReferenceError: drawCanvas is not defined
      

      This error occurs in this part of the onDraw function.

      QString jsCode = QString("drawCanvas('%1');").arg(imageDataArray.size());
      

      I don't know how to resolve this error.

      캡처47.JPG

      J Offline
      J Offline
      jsulm
      Lifetime Qt Champion
      wrote on 20 Nov 2023, 07:36 last edited by
      #2

      @MyNameIsQt said in (QWebEngineView )Passing argument values ​​to js function and drawing on canvas:

      webView.page()->setWebChannel(&channel);

      Are you aware that channel is a local variable and gets destroyed as soon as the method where it was created finishes?
      Please read documentation: https://doc.qt.io/qt-6/qwebenginepage.html#setWebChannel

      "Note: The page does not take ownership of the channel object."
      

      https://forum.qt.io/topic/113070/qt-code-of-conduct

      M 1 Reply Last reply 20 Nov 2023, 08:30
      2
      • J jsulm
        20 Nov 2023, 07:36

        @MyNameIsQt said in (QWebEngineView )Passing argument values ​​to js function and drawing on canvas:

        webView.page()->setWebChannel(&channel);

        Are you aware that channel is a local variable and gets destroyed as soon as the method where it was created finishes?
        Please read documentation: https://doc.qt.io/qt-6/qwebenginepage.html#setWebChannel

        "Note: The page does not take ownership of the channel object."
        
        M Offline
        M Offline
        MyNameIsQt
        wrote on 20 Nov 2023, 08:30 last edited by
        #3

        @jsulm
        I have set this as a member variable before. But I didn't think this was the problem since I had the same problem. Anyway, local variables are not good, so I changed it to a member variable and tried again. Again, the problem is the same. The canvas is not redrawn with the new file size. thank you

        class CBackground
        {
        private:
            _BACKGROUNDHEADER_ m_bkgndHeader;
        
            static QWebEngineView* webView;
            QWebChannel m_webChannel;
        
        // cpp
        
        QWebEngineView* CBackground::webView = nullptr;
        
        CBackground::CBackground(QIODevice* device) :    
             ....
            _b_filePath(false)
        {
            if (!webView) {
                webView = new QWebEngineView();       
            }
        
            webView->page()->setWebChannel(&m_webChannel);  // Set the web channel for the webView
            webView->load(QUrl::fromLocalFile(htmlPath));
              ....
        }
        
        CBackground::CBackground(const QString &filePathName) :    
             .....
            _b_filePath(true)
        {
            if (!webView) {
                webView = new QWebEngineView();      
            }
        
            webView->page()->setWebChannel(&m_webChannel);  // Set the web channel for the webView
            webView->load(QUrl::fromLocalFile(htmlPath));
        
        
        bool CBackground::onDraw()
        {
           if(!m_pBkgndImage->isNull()){
        
                if (m_pBkgndImage->colorSpace().isValid()){
                    m_pBkgndImage->convertToColorSpace(QColorSpace::SRgb);
                }
        
                QPoint point(0,0);
                point.rx() = m_bkgndHeader.Left;
                point.ry() = m_bkgndHeader.Top;
        
                QVariant imageVariant = QVariant::fromValue(*m_pBkgndImage);
        
                imageObject = new QObject();
                imageObject->setProperty("imageData", imageVariant);
              
                m_webChannel.registerObject("imageObject", imageObject);
        
                int imageSizeInBytes = m_pBkgndImage->bytesPerLine() * m_pBkgndImage->height();
        
                QByteArray imageDataArray(reinterpret_cast<const char*>(m_pBkgndImage->bits()), imageSizeInBytes);        
              
                QString jsCode = QString("drawCanvas('%1');").arg(imageDataArray.size());
        
                webView->page()->runJavaScript(jsCode);
        
                if(!m_pBkgndImage->isNull()){
                    delete m_pBkgndImage;
                    m_pBkgndImage = nullptr;
                }
        
                delete imageObject;
        
                return true;
        
            } else {
                QMessageBox::information(nullptr, "Drawing Image", "Failed 412");
                return false;
            }
        
            return false;
        }
        
        JonBJ 1 Reply Last reply 20 Nov 2023, 08:45
        0
        • M MyNameIsQt
          20 Nov 2023, 08:30

          @jsulm
          I have set this as a member variable before. But I didn't think this was the problem since I had the same problem. Anyway, local variables are not good, so I changed it to a member variable and tried again. Again, the problem is the same. The canvas is not redrawn with the new file size. thank you

          class CBackground
          {
          private:
              _BACKGROUNDHEADER_ m_bkgndHeader;
          
              static QWebEngineView* webView;
              QWebChannel m_webChannel;
          
          // cpp
          
          QWebEngineView* CBackground::webView = nullptr;
          
          CBackground::CBackground(QIODevice* device) :    
               ....
              _b_filePath(false)
          {
              if (!webView) {
                  webView = new QWebEngineView();       
              }
          
              webView->page()->setWebChannel(&m_webChannel);  // Set the web channel for the webView
              webView->load(QUrl::fromLocalFile(htmlPath));
                ....
          }
          
          CBackground::CBackground(const QString &filePathName) :    
               .....
              _b_filePath(true)
          {
              if (!webView) {
                  webView = new QWebEngineView();      
              }
          
              webView->page()->setWebChannel(&m_webChannel);  // Set the web channel for the webView
              webView->load(QUrl::fromLocalFile(htmlPath));
          
          
          bool CBackground::onDraw()
          {
             if(!m_pBkgndImage->isNull()){
          
                  if (m_pBkgndImage->colorSpace().isValid()){
                      m_pBkgndImage->convertToColorSpace(QColorSpace::SRgb);
                  }
          
                  QPoint point(0,0);
                  point.rx() = m_bkgndHeader.Left;
                  point.ry() = m_bkgndHeader.Top;
          
                  QVariant imageVariant = QVariant::fromValue(*m_pBkgndImage);
          
                  imageObject = new QObject();
                  imageObject->setProperty("imageData", imageVariant);
                
                  m_webChannel.registerObject("imageObject", imageObject);
          
                  int imageSizeInBytes = m_pBkgndImage->bytesPerLine() * m_pBkgndImage->height();
          
                  QByteArray imageDataArray(reinterpret_cast<const char*>(m_pBkgndImage->bits()), imageSizeInBytes);        
                
                  QString jsCode = QString("drawCanvas('%1');").arg(imageDataArray.size());
          
                  webView->page()->runJavaScript(jsCode);
          
                  if(!m_pBkgndImage->isNull()){
                      delete m_pBkgndImage;
                      m_pBkgndImage = nullptr;
                  }
          
                  delete imageObject;
          
                  return true;
          
              } else {
                  QMessageBox::information(nullptr, "Drawing Image", "Failed 412");
                  return false;
              }
          
              return false;
          }
          
          JonBJ Offline
          JonBJ Offline
          JonB
          wrote on 20 Nov 2023, 08:45 last edited by
          #4

          @MyNameIsQt
          To help diagnose what is going on, do not use console.error("Text "+imageData);. Do not put an expression here, only the imageData, and use console.log(imageData). See discussion of possibilities/other possibilities from e.g. https://stackoverflow.com/questions/957537/how-can-i-display-a-javascript-object

          M 1 Reply Last reply 20 Nov 2023, 09:14
          0
          • JonBJ JonB
            20 Nov 2023, 08:45

            @MyNameIsQt
            To help diagnose what is going on, do not use console.error("Text "+imageData);. Do not put an expression here, only the imageData, and use console.log(imageData). See discussion of possibilities/other possibilities from e.g. https://stackoverflow.com/questions/957537/how-can-i-display-a-javascript-object

            M Offline
            M Offline
            MyNameIsQt
            wrote on 20 Nov 2023, 09:14 last edited by
            #5

            @JonB said in (QWebEngineView )Passing argument values ​​to js function and drawing on canvas:

            Do not put an expression her

            I am currently using qt creator and console.error() can check the information in the application output window. But console.log() doesn't know how to check. Is there a way to check console.log() in qt creator?

            JonBJ 1 Reply Last reply 20 Nov 2023, 09:20
            0
            • M MyNameIsQt
              20 Nov 2023, 09:14

              @JonB said in (QWebEngineView )Passing argument values ​​to js function and drawing on canvas:

              Do not put an expression her

              I am currently using qt creator and console.error() can check the information in the application output window. But console.log() doesn't know how to check. Is there a way to check console.log() in qt creator?

              JonBJ Offline
              JonBJ Offline
              JonB
              wrote on 20 Nov 2023, 09:20 last edited by JonB
              #6

              @MyNameIsQt
              I don't know where console.log() goes (you sure it's not the same place as write()?). You could always run your application outside of Creator. But in the meantime try console.write(imageData), may be enough, the important thing is not to put an expression (like "Text "+imageData) there.

              Your code does nothing other than runJavaScript("drawCanvas('big-number')"). (Note that you pass the number as a string.) So why don't you remove everything about the image in your code and see how that behaves? We should be able to rule out all your image manipulation, and just not have the code there, please.

              Meanwhile you have never mentioned all the errors shown in your first screenshot, which are rather worrying....

              M 1 Reply Last reply 20 Nov 2023, 09:43
              0
              • JonBJ JonB
                20 Nov 2023, 09:20

                @MyNameIsQt
                I don't know where console.log() goes (you sure it's not the same place as write()?). You could always run your application outside of Creator. But in the meantime try console.write(imageData), may be enough, the important thing is not to put an expression (like "Text "+imageData) there.

                Your code does nothing other than runJavaScript("drawCanvas('big-number')"). (Note that you pass the number as a string.) So why don't you remove everything about the image in your code and see how that behaves? We should be able to rule out all your image manipulation, and just not have the code there, please.

                Meanwhile you have never mentioned all the errors shown in your first screenshot, which are rather worrying....

                M Offline
                M Offline
                MyNameIsQt
                wrote on 20 Nov 2023, 09:43 last edited by
                #7

                @JonB I understand it. thank you so much. :)

                1 Reply Last reply
                0
                • M MyNameIsQt referenced this topic on 30 Nov 2023, 11:53

                1/7

                20 Nov 2023, 07:31

                • 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