Вызов функции Qt со стороны Javascript (QWebView)

У меня есть проект Qt, который может загружать любую HTML-страницу в веб-представление. У меня есть следующий код в файле main.cpp:

#include "mainwindow.h"
#include <QApplication>
#include <QWebView>

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    QWebView *view = new QWebView();

    view->resize(400, 500);
    view->load(QUrl("file:///absolute/path/to/my/html/file.html"));
    view->show();

    return app.exec();
}

Это отлично работает, но я хочу вызвать функцию со стороны С++ через Javascript, загруженный в file.html (загруженный в QWebView).

Итак, имея следующую С++-функцию:

void sumOfNumbers (a, b)
{
   qDebug() << a + b;
}

Я хочу называть его со стороны JavaScript:

someMethod("sumOfNumber", 12, 23);

который будет печатать на консоли 35 (12 + 23).

Как я могу это сделать?

Ответ 1

Вам нужно определить методы, которые вы хотите вызвать в классе, который наследуется от QObject.

В QWebView вы можете вызвать page() для получения QWebPage. С помощью QWebPage вы можете вызвать mainFrame(), чтобы получить его QWebFrame. QWebFrame имеет метод addToJavaScriptWindowObject(), который позволяет привязать QObject к веб-контексту:

class MyObject {
public slots:
    void doSomething();
};

MyObject *foo = new MyObject;
myWebView->page()->mainFrame()->addJavaScriptToWindowObject("somefoo", foo);

Затем со стороны javascript я могу вызвать любой слот или метод Q_INVOKABLE в моем QObject, просто указав его по имени, указанному выше ( "somefoo" в этом случае):

somefoo.doSomething();

Дополнительная информация здесь: http://qt-project.org/doc/qt-5.1/qtwebkit/qwebframe.html#addToJavaScriptWindowObject

Обновить - добавление исходного примера.

main.cpp:

#include <QApplication>
#include <QDebug>
#include <QWebFrame>
#include <QWebPage>
#include <QWebView>

class MyJavaScriptOperations : public QObject {
    Q_OBJECT
public:
    Q_INVOKABLE void sumOfNumbers(int a, int b) {
        qDebug() << a + b;
    }
};

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    QWebView *view = new QWebView();
    view->resize(400, 500);
    view->page()->mainFrame()->addToJavaScriptWindowObject("myoperations", new MyJavaScriptOperations);
    view->load(QUrl("file:///path/to/my/index.html"));
    view->show();

    return a.exec();
}

#include "main.moc"

index.html

<html>
    <body>
        <script type="text/javascript">
            myoperations.sumOfNumbers(12, 23);
        </script>
    </body>
</html>