(QWebEngineView )Passing argument values to js function and drawing on canvas
-
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); }; */ }
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.
-
@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."
-
@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 youclass 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; }
-
@MyNameIsQt
To help diagnose what is going on, do not useconsole.error("Text "+imageData);
. Do not put an expression here, only theimageData
, and useconsole.log(imageData)
. See discussion of possibilities/other possibilities from e.g. https://stackoverflow.com/questions/957537/how-can-i-display-a-javascript-object -
@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?
-
@MyNameIsQt
I don't know whereconsole.log()
goes (you sure it's not the same place aswrite()
?). You could always run your application outside of Creator. But in the meantime tryconsole.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....
-