Método Invoke C++ desde webviews Javascript
qml qtwebkit (2)
En qt4 qml el qtwebkit 1.0 el componente webview tiene una propiedad javaScriptWindowObjects
. Lo utilicé para agregar javaScriptWindowObjects al contexto de mis páginas web javascript para llamar a las funciones c ++. al igual que
WebView{
url: "http://test.com"
anchors.fill: parent
scale: 1.0
javaScriptWindowObjects: QtObject {
WebView.windowObjectName: "native"
function foo(x, y) {
console.log("This is a call from javascript");
myCppHandler.fooNative(b,c);
}
}
}
entonces puedo llamarlo desde las páginas web javascript como tal
<script type="text/javascript">
native.foo(1,2)
</script>
pero en qt5 qml qtwebkit 3.0 no existe tal cosa como javaScriptWindowObjects
¿Cómo puedo lograr eso en qt5 qml?
Solo para el registro para hacer esto:
import QtQuick 2.0
import QtWebKit 3.0
import QtWebKit.experimental 1.0
Rectangle {
width: 1024
height: 768
WebView{
url: "http://localhost"
anchors.fill: parent
experimental.preferences.navigatorQtObjectEnabled: true
experimental.onMessageReceived: {
console.debug("get msg from javascript")
experimental.postMessage("HELLO")
}
} // webview
} // rectanlge
<html>
<body>
<h1>It just works!</h1>
<p>Play with me...</p>
<button onclick="nativecall();">test</button>
<div id="out"></div>
<script type="text/javascript">
function nativecall(){
console.log("will try native call");
var elem = document.getElementById("out").innerHTML="clicked";
navigator.qt.postMessage(''this is a js call'');
}
function jsCall(message){
var elem = document.getElementById("out").innerHTML="and the other way around " + message;
}
navigator.qt.onmessage = function(ev) {
jsCall(ev.data);
}
</script>
</body>
</html>
Qt 5.8.0 Enlace de QML y JavaScript
Código QML
import QtQuick 2.0
import QtWebEngine 1.4
import QtWebChannel 1.0
Item{
id:root
height: 500
width: 500
// Create WebChannel
WebChannel{
id:webChannel
}
//Now, let’s create an object that we want to publish to the HTML/JavaScript clients:
QtObject {
id: myObject
objectName: "myObject"
// the identifier under which this object
// will be known on the JavaScript side
//WebChannel.id: "webChannel"
property var send: function (arg) {
sendTextMessage(arg);
}
// signals, methods and properties are
// accessible to JavaScript code
signal someSignal(string message);
function someMethod(message) {
console.log(message);
someSignal(message);
return dataManager.getGeoLat();
}
property string hello: "world";
}
Rectangle{
anchors.fill: parent
color: "black"
WebEngineView{
id : webEnginView
anchors.fill: parent
url : dataManager.htmlURL();
webChannel: webChannel
}
}
Component.onCompleted: {
webChannel.registerObject("foo", myObject);
}
}
código HTML
<script type="text/javascript" src="qrc:/Map/qwebchannel.js"></script>
<script type="text/javascript">
new QWebChannel(qt.webChannelTransport, function(channel) {
// all published objects are available in channel.objects under
// the identifier set in their attached WebChannel.id property
var foo = channel.objects.foo;
// access a property
alert(foo.hello);
// connect to a signal
foo.someSignal.connect(function(message) {
alert("Got signal: " + message);
});
// invoke a method, and receive the return value asynchronously
foo.someMethod("bar", function(ret) {
alert("Got return value: " + ret);
});
});
</script>