qt html rest,javascript - How to use Qt WebEngine and QWebChannel? - Stack Overflow

I will summarize your questions as following:

Do I need QWebChannel to register JavaScript functions in the WebEngine?

Where can I find QWebChannel.js

How to communicate JS to C++ and C++ to JS

First, let take a simple code to play with:

#include

#include

#include

#include

// ... DEFINITIONS HERE

auto main( int argn, char* argv[] )-> int

{

QApplication app(argn, argv);

QWebEngineView browser;

browser.resize(QSize(800,600));

browser.show();

browser.load(QUrl("http://www.wikipedia.org"));

// .. SETUP HERE

QObject::connect(&browser, &QWebEngineView::loadFinished, [&browser](bool ok)

{

qDebug()<

// TEST CODE HERE

));

return app.exec();

}

Explanation: This code creates a Qt application, creates a QWebEngineView and set some minimal properties to make it visible.

A page from 'Wikipedia' is loaded inside and a signal/slot event is connected to print some log when the page is finally loaded.

How to call JS functions from C++ ?

You can simply call JS using QWebEnginePage::runJavaScript as following. Add this code to the TEST CODE HERE.

QString code = QStringLiteral(

R"DELIM(

var links = document.getElementsByTagName('a');

for ( var i=0; i

{

links[i].style.backgroundColor = 'yellow';

};

)DELIM");

browser.page()->runJavaScript(code, 42);

Explanation: This code execute some JS into the browser, on a context ID 42, avoiding collision with the default context of the page ID 0. The script change the background-color of each link to yellow.

How to call C++ from JS?

In this case, we need the QWebChannel mechanism to register C++ objects into JavaScript.

First, let create the C++ interface, callable from JS (in DEFINITION):

class JsInterface: public QObject

{

Q_OBJECT

public:

/// Log, for debugging

Q_INVOKABLE void log(const QString& str) const

{

qDebug() << "LOG from JS: " << str;

}

};

#include "main.moc"

Explanation: This code declare and define a QObject class with a simple log function inside. It is important to declare the function Q_INVOKABLE otherwise JavaScript can not find it!. As the declaration is inside the same file as the rest of the code, we include the auto-moc file from QT after (it is main.moc because my file is main.cpp).

Create a function in DEFINITION which return the JavaScript QWebChannel.js content. The content of QWebChannel.js can be found in your QT library (./5.12.2/Src/qtwebchannel/examples/webchannel/shared/qwebchannel.js or ./Examples/Qt-5.12.2/webchannel/shared/qwebchannel.js). You are free to load this directly in your page.

In DECLARATION section, append:

QString qWebChannelJs()

{

return R"DELIMITER(

// COPY HERE ALL THE FILE

)DELIMITER";

}

And we inject it in our code (Append it to TEST CODE HERE section):

browser.page()->runJavaScript(qWebChannelJs(), 42);

We need to setup the QWebChannel in C++ side (SETUP section):

QWebChannel channel;

JsInterface jsInterface;

browser.page()->setWebChannel(&channel, 42);

channel.registerObject(QString("JsInterface"), &jsInterface);

Explanation: We create a channel, the JsInterface object and register them into the browser. We need to use the same context id 42 (but could be another other number between 0 and 255).

Finally, in our JS code, we access the channel and call the function of the interface (append to TEST CODE section):

QString code2 = QStringLiteral(

R"DELIM(

window.webChannel = new QWebChannel(qt.webChannelTransport, function( channel)

{

var cpp = channel.objects.JsInterface;

cpp.log("Hello from JavaScript");

});

)DELIM");

browser.page()->runJavaScript(code2, 42);

Considerations

It is worth to mention that any call from C++ to JavaScript or from JavaScript to C++ goes through an Inter-Process-Communication (IPC) which is asynchronous. This means that runJavaScript returns before the JavaScript is executed, and that JavaScript returns before the C++ logis executed.

Full code

#include

#include

#include

#include

QString qWebChannelJs()

{

return R"DELIMITER(

// TODO INSERT JS code here

)DELIMITER";

}

class JsInterface: public QObject

{

Q_OBJECT

public:

/// Log, for debugging

Q_INVOKABLE void log(const QString& str) const

{

qDebug() << "LOG from JS: " << str;

}

};

#include "main.moc"

auto main( int argn, char* argv[] )-> int

{

QApplication app(argn, argv);

QWebEngineView browser;

browser.resize(QSize(800,600));

browser.show();

browser.load(QUrl("http://www.wikipedia.org"));

// .. SETUP HERE

QWebChannel channel;

JsInterface jsInterface;

browser.page()->setWebChannel(&channel, 42);

channel.registerObject(QString("JsInterface"), &jsInterface);

QObject::connect(&browser, &QWebEngineView::loadFinished, [&browser](bool ok)

{

qDebug()<

// TEST CODE HERE

QString code = QStringLiteral(

R"DELIM(

var links = document.getElementsByTagName('a');

for ( var i=0; i

{

links[i].style.backgroundColor = 'yellow';

};

)DELIM");

browser.page()->runJavaScript(code, 42);

browser.page()->runJavaScript(qWebChannelJs(), 42);

QString code2 = QStringLiteral(

R"DELIM(

window.webChannel = new QWebChannel(qt.webChannelTransport, function( channel)

{

var cpp = channel.objects.JsInterface;

cpp.log("Hello from JavaScript");

});

)DELIM");

browser.page()->runJavaScript(code2, 42);

});

return app.exec();

}

Related topics:

External documentation:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值