Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

HTML/JS and Qt



  • I used to do this in older version of Qt and it was way easier the communication between Qt and HTML/JS, today I started doing some research in how to do the same thing in this new Qt version and it's really complicated and the documentation didn't help much, it wasn't clear enough for me, idk.

    I wanted to create an HTML that has a button that when the user clicks that button JS will send that to Qt with a string and open a dialog.

    How can I do that using the current Qt version?


  • Moderators

    @Mr-Gisa
    With QtWebEngine you now have to do the most work in JS.
    See this



  • It was easy after all. Thank you very much.

    I just had to create an instance of QWebChannel and register the object and then on the HTML do something like that:

    <html>
    <head>
        <script src="qrc:///qtwebchannel/qwebchannel.js"></script>
    </head>
    <body>
        <button id="close" type="button">close</button>
    
        <script>
            window.onload = function() {
                new QWebChannel(qt.webChannelTransport, function(channel) {
                    window.mainWindow = channel.objects.mainWindow;
                });
    
                document.getElementById("close").addEventListener("click", function() {
                    mainWindow.close();
                });
            }
        </script>
    </body>
    </html>
    

    It's sad that the docs doesn't say much, I had to go and look for other examples on the internet.



  • @raven-worx , @Mr-Gisa ,

    This is interesting. I assume this will work just the same for me with a PyQt Qt app?
    Where do you get channel.objects.mainWindow from?



  • @JonB You have to register the object like this:

    auto channel = new QWebChannel(this);
    channel->registerObject("mainWindow", this);
    
    ui->browser->page()->setWebChannel(channel);
    

    BUT it was just a test, you will get a lot of warnings because the QMainWindow isn't suitable for that apparently. I created a class called CommandsBridge that extends QObject and that class is responsible for the communication using QWebChannel.

    Something like:

        mCommandsBridge = new CommandsBridge(this);
    
        auto channel = new QWebChannel(this);
        channel->registerObject("bridge", mCommandsBridge);
    
        ui->browser->page()->setWebChannel(channel);
    
        <script>
            window.onload = function() {
                new QWebChannel(qt.webChannelTransport, function(channel) {
                    window.bridge = channel.objects.bridge;
                });
    
                document.getElementById("button").addEventListener("click", function() {
                    bridge.say("yeah");
                });
            }
        </script>
    

    This is a simple slot:

    void CommandsBridge::say(const QString &message)
    {
        QMessageBox box;
        box.setWindowTitle("Example");
        box.setText(message);
        box.exec();
    }
    


  • @Mr-Gisa
    Thanks. For me it will come down to how channel->registerObject("bridge", mCommandsBridge); fares across Python/PyQt.



  • Isn't it something like this?

    channel = QtWebChannel.QWebChannel(self.ui.browser.page())
    self.ui.browser.page().setWebChannel(channel)
    channel.registerObject("bridge", ...)
    


  • @Mr-Gisa
    That's the syntax, but I'm wondering how registerObject() will fare when given a PyQt/Python object where you would pass a native C++ one. I don't know whether it expects certain behaviour that the Python level interferes with.



  • I'm not much of a Python user specially with Qt, I think that you have to make some tests in order to know how it works.


Log in to reply