[Qt-interest] Webkit, callbacks and QScriptValue
Nikhil Marathe
nsm.nikhil at gmail.com
Mon May 24 08:29:31 CEST 2010
Hi all,
I have a very vexing problem related to the QtScript/QtWebKit modules.
When using QtScript module and QScriptEngine, javascript functions can
be passed as first class values and received in C++ code. For example:
//////////////// test.h /////////////////////
#include <QObject>
#include <QScriptValue>
class Custom : public QObject
{
Q_OBJECT
public :
Q_INVOKABLE void callback( const QScriptValue &func );
};
/////////////// test.cpp //////////////////
#include <QObject>
#include <QtScript>
#include <QDebug>
#include <QApplication>
#include "test.h"
void Custom::callback( const QScriptValue &func )
{
qDebug() << func.isFunction();
}
int main(int argc, char **argv)
{
QApplication app(argc, argv);
QScriptEngine engine;
QScriptValue customObj = engine.newQObject(new Custom);
engine.globalObject().setProperty("needs", customObj);
engine.evaluate("needs.callback(function() {print('hello');})").toString();
app.exec();
}
///////////////////////////////////////////////
This will print 'true' since a function was passed to needs.callback.
Now consider the same 'Custom' object introduced into QWebFrame using
addToJavaScriptWindowObject()
/////////////// new test.cpp //////////////////
#include <QObject>
#include <QtScript>
#include <QDebug>
#include <QtWebKit>
#include <QApplication>
#include "test.h"
void Custom::callback( const QScriptValue &func )
{
qDebug() << func.isFunction();
}
int main(int argc, char **argv)
{
QApplication app(argc, argv);
// enable the console
QWebSettings::globalSettings()->setAttribute(QWebSettings::DeveloperExtrasEnabled,
true);
QWebInspector insp;
QWebView view;
view.load(QUrl("http://www.google.com"));
view.page()->currentFrame()->addToJavaScriptWindowObject("needs",
new Custom);
insp.setPage(view.page());
insp.show();
app.exec();
}
////////////////////////////////////////////////////////
Only the web inspector will be shown. Start the javascript console by
clicking the little icon at the bottom-left. Type:
needs.callback(function() {})
The error is: TypeError: cannot call callback(): unknown type `QScriptValue`
Why is this so? I would really appreciate if someone could point out
how to get this working. The weird thing is that QObject::connect()
invoked from within JavaScript accepts a callback function literal
perfectly fine. So how does it do that.
For example, if needs.callback was implemented in JavaScript:
needs.prototype.callback = function(func) {
this.someSignal.connect(func);
}
If I were to emit someSignal(), func would be called.
I tried using Q_DECLARE_METATYPE and friends to get QScriptValue to be
a valid type, but to no avail. Peeking into the qt sources
(src/3rdparty/webkit/WebKit/qt/tests/qwebframe/tst_qwebframe.cpp), we
see that there are tests to catch these kind of errors, but no test
which actually verifies custom types ( they are commented out ),
although a lot of setup hullabaloo is done at the top of the file with
Q_DECLARE_METATYPE.
Thanks in advance. I hope my problem is explained well, I can provide
more details if required. The .pro file is
/////////////// test.pro /////////////
SOURCES += test.cpp
HEADERS += test.h
CONFIG += qt debug
QT += script webkit
////////////////////////////////////////////
Regards,
Nikhil
More information about the Qt-interest-old
mailing list