1

I'm trying to read a JavaScript event from a QtWebEngine widget following these answer1, answer2.

In my code below, when i run the first JavaScript call, it does print the button element correctly:

view->page()->runJavaScript(R"(
    const button = document.getElementById("js-lang-list-button");
    console.log('\ntest:\n', button, "\n\n");
)");

However it doesn't print anything from the console.log inside of

new QWebChannel(qt.webChannelTransport, function (channel) { ... }

and the lambda connection never get called when i hover the button.

QObject::connect(&hover_helper, &HoverHelper::hovered, []() {
   qDebug() << "======hovered======" << QTime::currentTime();
});

Follow the code:

//webengine.h
#include <QtWebEngineWidgets>
#include <QFile>

// Subclass to read console.log messages
class WebEnginePage : public QWebEnginePage
{
    Q_OBJECT

public: 
    WebEnginePage(QWebEngineProfile* profile, QWebEngineView* parent = 0) {}

protected:
    virtual void javaScriptConsoleMessage(JavaScriptConsoleMessageLevel level, 
        const QString &message, int lineNumber, const QString &sourceID) {
        qDebug() << "console.log: " << message;
    }
};


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(); }
};

.cpp

#include "webengine.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    ui.setupUi(this);

    qputenv("QTWEBENGINE_REMOTE_DEBUGGING", "23654");

    QWebEngineView* view = new QWebEngineView(this);

    // Subclass the page so we can read
    // console.log(...) messages.
    WebEnginePage* page = new WebEnginePage(view->page()->profile(), view);
    view->setPage(page);
    view->page()->setBackgroundColor(Qt::transparent);

    HoverHelper hover_helper;

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

    view->page()->setWebChannel(&channel);

    QObject::connect(view, &QWebEngineView::loadFinished, [view]() {
       
        QStringList source_codes;
        source_codes << getSourceCode(QStringLiteral(":/qtwebchannel/qwebchannel.js"));

        // js-lang-list-button is the search button in the wikipedia page
        // looks like things inside of new QWebChannel isn't getting called
        // as it doesn't print the console.log() message
        source_codes << R"(
            new QWebChannel(qt.webChannelTransport, function (channel) 
            {            
                const button = document.getElementById("js-lang-list-button");

                console.log('button:', button);
                button.addEventListener('mouseover', myFunction);

                function myFunction() 
                {
                    console.log('mouseover');
                    channel.objects.qt_helper.onHovered()
                }
           });
        )";

        // This call is just to check if its finding the element
        view->page()->runJavaScript(R"(
            const button = document.getElementById("js-lang-list-button");
            console.log("\ntest:\n", button, "\n\n");
        )");

        view->page()->runJavaScript(source_codes.join("\n"));
        qDebug() << "loadFinished";
    });

    view->load(QUrl("https://www.wikipedia.com/"));
    
    // The connection never get called when i hover the
    // search button in the wikipedia page.
    QObject::connect(&hover_helper, &HoverHelper::hovered, []() {
        qDebug() << "======hovered======" << QTime::currentTime();
    });

    view->setGeometry(50, 50, 800, 600);
    view->show();

    return;
}

I have checked the value of source_codes and indeed looks like it contain some kind of source on it, i don't understand why things inside of new QWebChannel isn't getting called.

I have also tried loading a profile with the sources to the page instead of loading it through source_codes, but things from new QWebChannel also didn't get called.

I'm using Qt 6.4, Windows 10.

Cesar
  • 41
  • 2
  • 5
  • 16

0 Answers0