J. K.
J. K.

Reputation: 8368

How to fire a JavaScript event via C++ in QWebView

please note that I'm a complete beginner to Qt development.

I have a QWebView with a QObject added to the JavaScript window object. How do I fire a JS event on that object?

view->page()->mainFrame()->addToJavaScriptWindowObject(objName,obj);

I want to be able to listen to events using addEventListener.

window.objName.addEventListener('customEventName',function(e){ ... });

Thanks for any help.

Upvotes: 4

Views: 3407

Answers (2)

Kurt Pattyn
Kurt Pattyn

Reputation: 2798

In a recent project I used the following technique:

void VideoWebPage::urlLoaded(bool ok)
{
    static const QString javascript =
        "function installCallbacks()                                    " \
        "{                                                                  " \
        "   var videoTags = document.getElementsByTagName('object');        " \
        "   for (var i = 0; i < videoTags.length; ++i)                      " \
        "   {                                                               " \
        "        if (videoTags[i].type == 'application/x-qt-plugin')        " \
        "        {                                                          " \
        "            if (videoTags[i].playing)                              " \
        "            {                                                      " \
        "                videoTags[i].playing.connect(playingSlot); " \
        "            }                                                      " \
        "        }                                                          " \
        "    }                                                              " \
        "}                                                                  " \
        \
        "function playingSlot(videoId)                              " \
        "{                                                                  " \
        "    var playEvent=document.createEvent('Events');                  " \
        "    playEvent.initEvent('play', true, false);                      " \
        "    document.getElementById(videoId).dispatchEvent(playEvent); " \
        "}                                                                  " \
        "installCallbacks();                                            ";
    mainFrame()->evaluateJavaScript(javascript);
}

This method looks up all <object> tags and connects the playing signal to the Javascript function playingSlot(). The playingSlot() function in its turn creates an Event object with the name play and dispatches it as an ordinary DOM event. The HTML file then looks like:

<html>
<head>
<script language="text/javascript">
    void init()
    {
        document.getElementById('id1').addEventListener('play', onPlay);
    }
    void onPlay(event)
    {
        alert('playing');
    }
</script>
</head>
<body onload='init()'>
    <object id='id1' type='application/x-qt-plugin'>
    </object>
</body>
</html>

This is of course working with Qt plugin Widgets. I did not test it with plain HTML (i.e. where no Qt plugins are used).

Upvotes: 1

Jakub Wieczorek
Jakub Wieczorek

Reputation: 1919

You cannot do that. Only nodes in a DOM tree can fire events and the object you're injecting is not a node. I suggest you consider using the signal-slot mechanism instead. You can connect a slot in JS to a signal that you'll be emitting in your C++ code:

window.objectName.signalName.connect(slot);

slot is just an JS function, that you'll declare in the JS part of your code:

function slot(arg1, arg2, ...)
{
}

It takes as many arguments as are declared in the signal's signature.

Upvotes: 4

Related Questions