<div dir="ltr"><div>When I call the runJavaScript function of QWebEnginePage with a callback I can't block the python code on this call. I've tried sleeping, "spinning the event loop" (Kovid Goyal - <a href="https://riverbankcomputing.com/pipermail/pyqt/2015-January/035324.html">https://riverbankcomputing.com/pipermail/pyqt/2015-January/035324.html</a>) and a combination of both. The example below shows how the "call_js_with_callback" keeps waiting.</div><div><br></div><div>When this while loop is removed from "call_js_with_callback" the callback actually happens. This means in an asynchronous environment this would not be an issue, but when porting a legacy project which was not written with asynchronous behavior in mind there is no quick way to port. Can anyone tell me if this is correct or if I've made a mistake and/or there is a workaround I can use?</div><div><br></div><div>Another interesting thing is that a callback method declared as I have it will crash unless the @pyqtSlot() is changed in an @pyqtSlot(str) (or something similar I assume). With @pyqtSlot() the callback will retrieve None as parameter and a silent crash of the application happens. Maybe this can be added to the <a href="http://pyqt.sourceforge.net/Docs/PyQt5/api/qwebenginepage.html">http://pyqt.sourceforge.net/Docs/PyQt5/api/qwebenginepage.html</a> page or an error message can be returned when the callback fails.</div><div><br></div><div>Regards and thanks in advance,</div><div><br></div><div>Daan Veltman</div><div><br></div><div><font face="monospace, monospace">from PyQt5.Qt import *</font></div><div><font face="monospace, monospace">from PyQt5.QtWebEngineWidgets import QWebEnginePage, QWebEngineScript, QWebEngineView</font></div><div><font face="monospace, monospace">from time import sleep</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">class WebPage(QWebEnginePage):</font></div><div><font face="monospace, monospace">    javascript_is_ready = False</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">    @pyqtSlot()</font></div><div><font face="monospace, monospace">    def html_ready(self):</font></div><div><font face="monospace, monospace">        print 'html_ready'</font></div><div><font face="monospace, monospace">        self.html_ready = True</font></div><div><font face="monospace, monospace">        self.call_js_with_callback()</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">    def call_js_with_callback(self):</font></div><div><font face="monospace, monospace">        print 'call_js_with_callback'</font></div><div><font face="monospace, monospace">        self.runJavaScript('js_function("with_callback")', self.callback)</font></div><div><font face="monospace, monospace">        while not self.javascript_is_ready:</font></div><div><font face="monospace, monospace">            print 'processing events'</font></div><div><font face="monospace, monospace">            QApplication.instance().processEvents(QEventLoop.ExcludeUserInputEvents | QEventLoop.ExcludeSocketNotifiers | QEventLoop.WaitForMoreEvents)</font></div><div><font face="monospace, monospace">            sleep(0.5)<br></font></div><div><font face="monospace, monospace">        print 'through with sleeping!'</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">    @pyqtSlot(str)</font></div><div><font face="monospace, monospace">    def callback(self, none):</font></div><div><font face="monospace, monospace">        print 'calling back!', none</font></div><div><font face="monospace, monospace">        self.javascript_is_ready = True</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">app = QApplication([])</font></div><div><font face="monospace, monospace">page = WebPage()</font></div><div><font face="monospace, monospace">view = QWebEngineView()</font></div><div><font face="monospace, monospace">view.setPage(page)</font></div><div><font face="monospace, monospace">channel = QWebChannel(page)</font></div><div><font face="monospace, monospace">channel.registerObject('page', page)</font></div><div><font face="monospace, monospace">page.setWebChannel(channel)</font></div><div><font face="monospace, monospace">view.setHtml(</font></div><div><font face="monospace, monospace">            '<html>' + '\n'</font></div><div><font face="monospace, monospace">            '  <body>' + '\n'</font></div><div><font face="monospace, monospace">            '    <script src="<a href="https://ajax.googleapis.com/ajax/libs/jquery/1.12.2/jquery.min.js">https://ajax.googleapis.com/ajax/libs/jquery/1.12.2/jquery.min.js</a>"></script>' + '\n'</font></div><div><font face="monospace, monospace">            '    <script type="text/javascript" src="<a href="https://rawgit.com/qtproject/qtwebchannel/dev/src/webchannel/qwebchannel.js">https://rawgit.com/qtproject/qtwebchannel/dev/src/webchannel/qwebchannel.js</a>"></script>' + '\n'</font></div><div><font face="monospace, monospace">            '    <p>Hello world!</p>' + '\n'</font></div><div><font face="monospace, monospace">            '    <script type="text/javascript">' + '\n'</font></div><div><font face="monospace, monospace">            '        function js_function(text) {' + '\n'</font></div><div><font face="monospace, monospace">            '            alert("js_function! " + text);' + '\n'</font></div><div><font face="monospace, monospace">            '            }' + '\n'</font></div><div><font face="monospace, monospace">            '    </script>' + '\n'</font></div><div><font face="monospace, monospace">            '    <script type="text/javascript">' + '\n'</font></div><div><font face="monospace, monospace">            '        $(document).ready(function(){' + '\n'</font></div><div><font face="monospace, monospace">            '            alert("document ready");' + '\n'</font></div><div><font face="monospace, monospace">            '            new QWebChannel(qt.webChannelTransport, function (channel) {' + '\n'</font></div><div><font face="monospace, monospace">            '                page = channel.objects.page;' + '\n'</font></div><div><font face="monospace, monospace">            '                page.html_ready();' + '\n'</font></div><div><font face="monospace, monospace">            '            });' + '\n'</font></div><div><font face="monospace, monospace">            '        });' + '\n'</font></div><div><font face="monospace, monospace">            '    </script>' + '\n'</font></div><div><font face="monospace, monospace">            '    <p>Done!</p>' + '\n'</font></div><div><font face="monospace, monospace">            '  </body>' + '\n'</font></div><div><font face="monospace, monospace">            '</html>')</font></div><div><font face="monospace, monospace">view.show()</font></div><div><font face="monospace, monospace">app.exec_()</font></div><div><font face="monospace, monospace">print 'exit'</font></div><div><br></div></div>