Inspect element (Html code) using QWebEngineView
-
wrote on 3 Mar 2020, 18:49 last edited by
Hello, is it possible to display a web page into a QWebEngineView, click on an element in the page, and get the corresponding HTML code of the element ? Like when right-clicking "Inspect" on a element in Chrome.
-
Hello, is it possible to display a web page into a QWebEngineView, click on an element in the page, and get the corresponding HTML code of the element ? Like when right-clicking "Inspect" on a element in Chrome.
@cpper
if you actually want to inspect the element, qtwebengine provides debug tools via a desktop chrome browser -
wrote on 3 Mar 2020, 22:12 last edited by
I don't need the debug tools window (like the one you get with F12 in chrome), I just want to get the html source of the clicked element.
-
I don't need the debug tools window (like the one you get with F12 in chrome), I just want to get the html source of the clicked element.
Moderatorswrote on 4 Mar 2020, 07:48 last edited by raven-worx 3 Apr 2020, 19:50@cpper
ok, then there is only the way using QtWebChannel.
You will need to inject the webchannel bootstrapping JS and your custom JS (which then actually does all the work and sends - for example theinnerHTML
property of a DOM element back to your C++ class via the webchannel)There are already some examples here in the forum, how to bootstap QtWebChannel
QWebEnginePage* page = ... QWebChannel* myChannel = new QWebChannel(page); page->setWebChannel(channel); channel->registerObject( "myCppObj", myCppObj); // myCppObj should be an QObject with properties and invokable methods // make sure qwebchannel.js is executed, or automatically injected for all sites // -> load page
For automatic injection of JS code see here: https://lists.qt-project.org/pipermail/qtwebengine/2016-March/000338.html
const char s_qWebChannelAdditionalScript[] = "new QWebChannel(qt.webChannelTransport, function(channel) {" " window.exported_object = channel.objects.exported_object;" "});"; QWebEngineProfile *WebEngineView::prepareProfile() { QWebEngineProfile *profile = new QWebEngineProfile("Profile", this); ... // Preparing qwebchannel.js for injection QFile qWebChannelJsFile(":/qtwebchannel/qwebchannel.js"); if(! qWebChannelJsFile.open(QIODevice::ReadOnly)) { MY_ERROR("Failed to load qwebchannel.js with error: " + qWebChannelJsFile.errorString()); } else { QByteArray qWebChannelJs = qWebChannelJsFile.readAll(); qWebChannelJs.append(QString(s_qWebChannelAdditionalScript)); QWebEngineScript script; script.setSourceCode(qWebChannelJs); script.setName("qwebchannel.js"); script.setWorldId(QWebEngineScript::MainWorld); script.setInjectionPoint(QWebEngineScript::DocumentCreation); script.setRunsOnSubFrames(false); profile->scripts()->insert(script); } return profile; }
-
@cpper
ok, then there is only the way using QtWebChannel.
You will need to inject the webchannel bootstrapping JS and your custom JS (which then actually does all the work and sends - for example theinnerHTML
property of a DOM element back to your C++ class via the webchannel)There are already some examples here in the forum, how to bootstap QtWebChannel
QWebEnginePage* page = ... QWebChannel* myChannel = new QWebChannel(page); page->setWebChannel(channel); channel->registerObject( "myCppObj", myCppObj); // myCppObj should be an QObject with properties and invokable methods // make sure qwebchannel.js is executed, or automatically injected for all sites // -> load page
For automatic injection of JS code see here: https://lists.qt-project.org/pipermail/qtwebengine/2016-March/000338.html
const char s_qWebChannelAdditionalScript[] = "new QWebChannel(qt.webChannelTransport, function(channel) {" " window.exported_object = channel.objects.exported_object;" "});"; QWebEngineProfile *WebEngineView::prepareProfile() { QWebEngineProfile *profile = new QWebEngineProfile("Profile", this); ... // Preparing qwebchannel.js for injection QFile qWebChannelJsFile(":/qtwebchannel/qwebchannel.js"); if(! qWebChannelJsFile.open(QIODevice::ReadOnly)) { MY_ERROR("Failed to load qwebchannel.js with error: " + qWebChannelJsFile.errorString()); } else { QByteArray qWebChannelJs = qWebChannelJsFile.readAll(); qWebChannelJs.append(QString(s_qWebChannelAdditionalScript)); QWebEngineScript script; script.setSourceCode(qWebChannelJs); script.setName("qwebchannel.js"); script.setWorldId(QWebEngineScript::MainWorld); script.setInjectionPoint(QWebEngineScript::DocumentCreation); script.setRunsOnSubFrames(false); profile->scripts()->insert(script); } return profile; }
wrote on 4 Mar 2020, 08:37 last edited by JonB 3 Apr 2020, 08:38@raven-worx
May I pick you up on this, as it seems it may be totally germane to an issue I am presently struggling with?As briefly as possible. I am about to launch out on an area where we have decided to use
QWebEnginePage
with JavaScript to offer something (chart drawing from a JS library). Unlike from C++ or PyQt, we are using PySide2 and that does not implement the methods which involve a "callback" from JS code to Qt code, e.g. none of theQWebEnginePage::runJavaScript()
overloads which useQWebEngineCallback<const QVariant &> &resultCallback
. The PySide2 folks are aware of this missing feature, but have decided to do nothing about it and offer no workaround.As I understand it, that means I will be able to push JS stuff to
QWebEnginePage
OK, but will not be able to read anything back from it, should I need to? Which worries me. Are you saying that if I read up onQWebChannel
I will be able to use that to get stuff out from running JS in the page? Thank you. -
wrote on 4 Mar 2020, 13:42 last edited by cpper 3 Apr 2020, 13:42
@raven-worx Alright, thanks for the sample code :)
-
@raven-worx
May I pick you up on this, as it seems it may be totally germane to an issue I am presently struggling with?As briefly as possible. I am about to launch out on an area where we have decided to use
QWebEnginePage
with JavaScript to offer something (chart drawing from a JS library). Unlike from C++ or PyQt, we are using PySide2 and that does not implement the methods which involve a "callback" from JS code to Qt code, e.g. none of theQWebEnginePage::runJavaScript()
overloads which useQWebEngineCallback<const QVariant &> &resultCallback
. The PySide2 folks are aware of this missing feature, but have decided to do nothing about it and offer no workaround.As I understand it, that means I will be able to push JS stuff to
QWebEnginePage
OK, but will not be able to read anything back from it, should I need to? Which worries me. Are you saying that if I read up onQWebChannel
I will be able to use that to get stuff out from running JS in the page? Thank you.Moderatorswrote on 4 Mar 2020, 19:47 last edited by raven-worx 3 Apr 2020, 20:40@JonB said in Inspect element (Html code) using QWebEngineView:
Are you saying that if I read up on QWebChannel I will be able to use that to get stuff out from running JS in the page? Thank you.
yes. communication is serialized via QtWebChannel from JS code to C++ code (QObject) and vice versa.
The JS code then can call invokable methods and access the QObjects properties and connect to its signals. See the examples -
wrote on 31 Mar 2021, 14:03 last edited by
Can you provide please a simple code to clear the local storage ?
-
@Belfix How is your question related to this thread?