How to pass a function "pointer" from JavaScript to a slot?
in JavaScript:
function f1()
{
alert("f1");
}
qtclass.submit(f1);
and in Qt:
public slots:
void submit(void * ptr)
{
(void)ptr;
}
I need the "f1", function to get fired in the JavaScript from the c++, once some processing is done. Also I do not know in advance the name of the function pointer.
How to pass a function "pointer" from JavaScript to a slot?
in JavaScript:
function f1()
{
alert("f1");
}
qtclass.submit(f1);
and in Qt:
public slots:
void submit(void * ptr)
{
(void)ptr;
}
I need the "f1", function to get fired in the JavaScript from the c++, once some processing is done. Also I do not know in advance the name of the function pointer.
Share Improve this question edited Dec 10, 2016 at 14:45 Mr_and_Mrs_D 34k45 gold badges189 silver badges369 bronze badges asked Feb 12, 2011 at 1:16 user457015user457015 9814 gold badges14 silver badges33 bronze badges4 Answers
Reset to default 9you should be able to execute your script using QWebFrame::evaluateJavaScript method. See if an example below would work for you:
initializing webview:
QWebView *view = new QWebView(this->centralWidget());
view->load(QUrl("file:///home//test.html"));
connect(view, SIGNAL(loadFinished(bool)), this, SLOT(loadFinished(bool)));
loadFinished signal handler:
void MyTestWindow::loadFinished(bool)
{
QVariant f1result = ((QWebView*)sender())->page()->mainFrame()->evaluateJavaScript("f1('test param')");
qDebug() << f1result.toString();
}
test.html:
<head>
<script LANGUAGE="JavaScript">
function f1 (s)
{
alert (s)
return "f1 result"
}
</script>
</head>
<body>
test html
</body>
evaluateJavaScript should trigger an alert message box and return QVariant with f1 function result.
hope this helps, regards
You could solve this in another way, by using Qt signals, as follows:
class qtclass
{
signals:
void done(QString message);
};
In your HTML file you can connect to this signal, like this:
qtclass.done.connect(f1);
function f1(message)
{
alert('f1 called from qtclass with message' + message);
}
Then you C++ class does not need to know about the javascript function.
While it wouldn't work in all cases, you could simply pass a string to your slot. Your slot could then use evaluateJavaScript (as serge has suggested) to call the function.
function f1()
{
alert("f1");
}
qtclass.submit("f1");
and in Qt:
public slots:
void submit(QString functionName)
{
m_pWebView->page()->mainFrame()->evaluateJavaScript(functionName + "()");
}
I have one entire working solution here - using slots. However, I couldn't get the signals working as suggested by Kurt.
#include <QtGui/QApplication>
#include <QApplication>
#include <QDebug>
#include <QWebFrame>
#include <QWebPage>
#include <QWebView>
class MyJavaScriptOperations : public QObject {
Q_OBJECT
public:
QWebView *view;
MyJavaScriptOperations();
Q_INVOKABLE qint32 MultOfNumbers(int a, int b) {
qDebug() << a * b;
return (a*b);
}
public slots:
void callback();
public:
void firecb();
signals:
void done();
};
MyJavaScriptOperations::MyJavaScriptOperations()
{
view = new QWebView();
view->resize(400, 500);
connect(view->page()->mainFrame(), SIGNAL(javaScriptWindowObjectCleared()), this, SLOT(callback()));
view->load(QUrl("./shreyas.html"));
view->show();
qDebug()<<view;
}
void MyJavaScriptOperations::callback()
{
qDebug()<<"Sending hello text";
QString function = "f1()";
view->page()->mainFrame()->addToJavaScriptWindowObject("myoperations", this);
view->page()->mainFrame()->evaluateJavaScript("f1()");
done();
}
void MyJavaScriptOperations::firecb()
{
qDebug()<<"Emitting Signal";
done();
}
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MyJavaScriptOperations *jvs = new MyJavaScriptOperations;
jvs->firecb();
return a.exec();
}
#include "main.moc"
The html file changes are -
<head>
<script LANGUAGE="JavaScript">
function f1()
{
alert('f1 called from qtclass with message');
document.write("HELLLLLLLLL");
}
myoperations.callback(f1);
function f2()
{
var result = myoperations.MultOfNumbers(3,7);
document.write(result);
alert('f1 called from qtclass with message');
}
function f3()
{
alert('f3');
}
myoperations.done.connect(f3);
</script>
</head>
<body>
test html
<input type="button" value="click" onclick="f2()">
</body>