PDA

View Full Version : Call a JavaScript function from C++ using QtWebkit



Rastersoft
30th March 2012, 15:50
Hi all:

Some time ago I developed a browser using WebkitGTK, and added some extra javascript objects to implement a framework I needed for a project.

Now I need to rewrite this browser using QtWebKit. I've been successful in calling C++ methods from JavaScript, but now I need to register a JavaScript callback, and be able to call it from C++. In the original system I built a C function which received an object as parameter (using JSValueToObject to convert the value received by the function to an object). That object was the JavaScript function to be called as callback. An example: this Javascript code registers the JavaScript callback called cb_function:


bool cb_function(param1, param2) {

alert("This is the callback, called with "+param1);

}

my_c_class.set_callback(cb_function);


Here, I define the cb_function callback, and send it as a parameter to the underlying framework. Then, in C, I used JSObjectCallAsFunction() to call the JavaScript function whenever I needed, sending to it some parameters.

What I need to know is how to do this with QtWebKit instead. I presume that the first part needs to use a Q_INVOKABLE method (called, in this case, set_callback) which receives the function. The problem is which type to use. If I put a String, I receive a text transcript of the function itself, not an object that I can call. Should it need to be a QVariant or a QObject?

And now the second part: how can I call from C++ that function I received?

Thanks!!!

Spitfire
2nd April 2012, 16:58
QWebView::page()->mainFrame()->evaluateJavaScript( "some_js_function()" ); should do the trick.

Rastersoft
3rd April 2012, 15:24
Unfortunately that's not a solution, because the callback can be inside an iFrame. In that case, your solution won't work :(

wysota
3rd April 2012, 15:49
Unfortunately that's not a solution, because the callback can be inside an iFrame. In that case, your solution won't work :(

How would you implement it from within the HTML page code?

Rastersoft
3rd April 2012, 16:15
Inside the iFrame is loaded a page that has


bool cb_function(param1, param2) {

alert("This is the callback, called with "+param1);

}

my_c_class.set_callback(cb_function);

If, now, from the C++ code I receive this as a string, it will contain "bool cb_function...". If I use that way, I would be calling "cb_function" in the main page, not inside the iFrame.

wysota
3rd April 2012, 16:38
This is a trivial case where the callback is registered in the same place where the function is called, I doubt you really have a case like that. From what I understand an equivalent would be to register a callback from the main page to a function that lives in some subframe, right? So how would you do that in pure javascript?

Spitfire
3rd April 2012, 16:46
You didn't answer wysota's question.

How do you call function inside iFrame from the parent document?
If you can answer this question - you will answer yourself how to call it from c as the approach is the same.

As an alternative you can try QWebPage::currentFrame() or QWebPage::frameAt().

If you don't know how to call js inside iFrame from parent document consider this:

QWebView::page()->mainFrame()->evaluateJavaScript( "function call_iFrame() { document.getElementById('iframe_id').contentWindow .method_inside_iframe(); }" )
That should get you going.

SlyMaximus
13th May 2014, 22:21
As an alternative you can try QWebPage::currentFrame() or QWebPage::frameAt().

If you don't know how to call js inside iFrame from parent document consider this:

QWebView::page()->mainFrame()->evaluateJavaScript( "function call_iFrame() { document.getElementById('iframe_id').contentWindow .method_inside_iframe(); }" )
That should get you going.

I am sorry I am resurrecting this topic, but following it I think this topic is incomplete and my question might start from this point.
Into an application that use a WebView I am loading some web content. Trying to execute a JavaScript code that call a alert() window directly into evaluateJavaScript() is fine, but calling it into a function it fails.


QString strTest1 ("alert(\"this is sly!\"); null ");
QVariant f1result = webView->page()->mainFrame()->evaluateJavaScript( strTest1 ); // fine
QString strTest2 ("function alert_something() { alert(\"this is sly!\"); } ");
QVariant f2result = webView->page()->mainFrame()->evaluateJavaScript( strTest2 ); // bad

qDebug() << f2result.toString(); // returns nothing

I can't figure why calling that trivial function call fails... Ideas?

anda_skoa
14th May 2014, 10:26
Your second JavaScript snippet only contains a function definition, not a call to that function.

Cheers,
_

SlyMaximus
14th May 2014, 13:03
Your second JavaScript snippet only contains a function definition, not a call to that function.

Cheers,
_
Loolll! I think I was blind, of-course we need that call. :cool:
10x!