2

I have to capture a event dispatched from webpage with JavaScript, and then connect it to a slot in my MainWindow class. Something aproaching to that:

QWebEngineView *view;
view->load(QUrl("https://test.com/"));

connect(view->my_element, &DOMElement::hover, this, &MainWindow::elementHovered);

What is the most algorithmic way to do it in C++?

1 Answer 1

3

If you want to track the events of some element of the DOM and notify about it to a C++ element then you must use Qt WebChannel:

#include <QtWebEngineWidgets>

static QString getSourceCode(const QString & filename){
    QFile file(filename);
    if(!file.open(QIODevice::ReadOnly))
        return {};
    return file.readAll();
}

class HoverHelper: public QObject{
    Q_OBJECT
public:
    using QObject::QObject;
Q_SIGNALS:
    void hovered();
public Q_SLOTS:
    void onHovered(){ Q_EMIT hovered(); }
};

#include "main.moc"

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

    HoverHelper hover_helper;

    QWebChannel channel;
    channel.registerObject("qt_helper", &hover_helper);

    QWebEngineView view;
    view.page()->setWebChannel(&channel);
    QObject::connect(&view, &QWebEngineView::loadFinished, [&view](){
        QStringList source_codes;
        source_codes << getSourceCode(QStringLiteral(":/qtwebchannel/qwebchannel.js"));
        source_codes << R"(
                        new QWebChannel(qt.webChannelTransport, function (channel) {
                            var e = document.getElementById("LearnMore1")
                            e.addEventListener("mouseover", function(){
                                channel.objects.qt_helper.onHovered()
                            });
                        });
                        )";
        view.page()->runJavaScript(source_codes.join("\n"));
        qDebug() << "loadFinished";
    });

    view.resize(640, 480);
    view.load(QUrl("https://test.com/"));
    view.show();

    QObject::connect(&hover_helper, &HoverHelper::hovered, [](){
       qDebug() << "hovered" << QTime::currentTime();
    });
    return a.exec();
}
Sign up to request clarification or add additional context in comments.

2 Comments

Inheriting QObject is required in this example? Thanks!
@JoãoSantos Yes, I recommend you check the Qt WebChannel docs but in simple words: The QMetaObject is used to map the QObjects from javascript

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.