Qt Forum

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Unsolved

    In QT 5, does javascript's window.postMessage work in a QWebView ?

    General and Desktop
    2
    2
    2712
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • A
      Arfy last edited by

      Same code trying to send a message between browser's Window, see doc/example
      https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage
      works in Chrome/Firefox/IE but not in a QT application with a main QWebView with childs' QWebView.

      Thanks,
      Arfy

      M 1 Reply Last reply Reply Quote 0
      • M
        maximo @Arfy last edited by

        @Arfy said:

        https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage

        I got this working. You have to include the <!DOCTYPE html> in your HTML to trigger the HTML5 handler, because this is an HTML5 feature only. I also used Qt 5.5's QWebView widget in a widget app and didn't do this the QML route. I found the tech preview of QtWebView quite flaky and documented this here:

        http://forum.qt.io/topic/60798/applestore-and-qtwebview-webkit-qt5-5/10

        So, using the stable QWebView widget approach, I used an IFRAME inside my web page and could communicate between the IFRAME child and its parent by using postMessage().

        In the parent document, you have to do this:

        $(document).ready(function(){
          $('#myIFRAME').load(function(){
            $(this)[0].contentWindow.postMessage('setEvent();','*');
          });
        });
        

        In the IFRAME child document, you need to add this:

        var goLastEvent = null;
        //respond to events
        window.addEventListener('message',function(event) {
          goLastEvent = event;
          // add code here to parse event.data, which is your message.
        });
        

        Then, when the iframe needs to talk back to the parent document, it can do it like so:

        goLastEvent.source.postMessage('runFoo();','*');
        

        Of course, the parent document then needs this code to receive that message:

        var goLastEvent = null;
        //respond to events
        window.addEventListener('message',function(event) {
          goLastEvent = event;
          // add code here to parse event.data, which is your message.
        });
        

        That said, you may be surprised to find out that window.parent.foo() is possible, in other words, direct function calls, instead of having to do message passing between IFRAME and parent. However, this is only when run inside a Qt widget application -- it won't work if you try to load your HTML pages in your browser. (Well, note that I'm using file::// URLs instead of remote URLs -- your experience may vary on remote URLs.)

        And then, once you learn this, you can read up on the QWebView bridge so that you can inject a C++ class into your DOM so that the Javascript can call C++ object methods directly without having to do message passing. However, my tests showed that this bridge only works with the parent document. So, if you need it in an IFRAME child, you'll have to get the IFRAME child to either do the window.parent.foo() technique, or use the postMessage API, in order to tell the parent to do some task with the DOM-injected C++ object.

        Last but not least -- this is all going to change when QtWebEngine comes out in the next version of Qt after 5.5. I talk a little about what I know about it here:

        http://forum.qt.io/topic/60798/applestore-and-qtwebview-webkit-qt5-5/10

        1 Reply Last reply Reply Quote 0
        • First post
          Last post