[PyQt] PyQt5 QtWebEngine: can't block python till javascript is finished with a callback function

Detlev Offenbach detlev at die-offenbachs.de
Fri May 6 14:21:40 BST 2016


Hi,

you may have a look into the eric sources (default branch). I’ve included an execJavaScript method that works synchroneously. See the eric web site for how to clone the eric repository.

Detlev

> Am 06.05.2016 um 11:28 schrieb Daan V. <daanv1987 at gmail.com>:
> 
> 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 - https://riverbankcomputing.com/pipermail/pyqt/2015-January/035324.html <https://riverbankcomputing.com/pipermail/pyqt/2015-January/035324.html>) and a combination of both. The example below shows how the "call_js_with_callback" keeps waiting.
> 
> 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?
> 
> 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 http://pyqt.sourceforge.net/Docs/PyQt5/api/qwebenginepage.html <http://pyqt.sourceforge.net/Docs/PyQt5/api/qwebenginepage.html> page or an error message can be returned when the callback fails.
> 
> Regards and thanks in advance,
> 
> Daan Veltman
> 
> from PyQt5.Qt import *
> from PyQt5.QtWebEngineWidgets import QWebEnginePage, QWebEngineScript, QWebEngineView
> from time import sleep
> 
> class WebPage(QWebEnginePage):
>     javascript_is_ready = False
> 
>     @pyqtSlot()
>     def html_ready(self):
>         print 'html_ready'
>         self.html_ready = True
>         self.call_js_with_callback()
> 
>     def call_js_with_callback(self):
>         print 'call_js_with_callback'
>         self.runJavaScript('js_function("with_callback")', self.callback)
>         while not self.javascript_is_ready:
>             print 'processing events'
>             QApplication.instance().processEvents(QEventLoop.ExcludeUserInputEvents | QEventLoop.ExcludeSocketNotifiers | QEventLoop.WaitForMoreEvents)
>             sleep(0.5)
>         print 'through with sleeping!'
> 
>     @pyqtSlot(str)
>     def callback(self, none):
>         print 'calling back!', none
>         self.javascript_is_ready = True
> 
> 
> app = QApplication([])
> page = WebPage()
> view = QWebEngineView()
> view.setPage(page)
> channel = QWebChannel(page)
> channel.registerObject('page', page)
> page.setWebChannel(channel)
> view.setHtml(
>             '<html>' + '\n'
>             '  <body>' + '\n'
>             '    <script src="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>"></script>' + '\n'
>             '    <script type="text/javascript" src="https://rawgit.com/qtproject/qtwebchannel/dev/src/webchannel/qwebchannel.js <https://rawgit.com/qtproject/qtwebchannel/dev/src/webchannel/qwebchannel.js>"></script>' + '\n'
>             '    <p>Hello world!</p>' + '\n'
>             '    <script type="text/javascript">' + '\n'
>             '        function js_function(text) {' + '\n'
>             '            alert("js_function! " + text);' + '\n'
>             '            }' + '\n'
>             '    </script>' + '\n'
>             '    <script type="text/javascript">' + '\n'
>             '        $(document).ready(function(){' + '\n'
>             '            alert("document ready");' + '\n'
>             '            new QWebChannel(qt.webChannelTransport, function (channel) {' + '\n'
>             '                page = channel.objects.page;' + '\n'
>             '                page.html_ready();' + '\n'
>             '            });' + '\n'
>             '        });' + '\n'
>             '    </script>' + '\n'
>             '    <p>Done!</p>' + '\n'
>             '  </body>' + '\n'
>             '</html>')
> view.show()
> app.exec_()
> print 'exit'
> 
> _______________________________________________
> PyQt mailing list    PyQt at riverbankcomputing.com
> https://www.riverbankcomputing.com/mailman/listinfo/pyqt

Detlev Offenbach
detlev at die-offenbachs.de



-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://www.riverbankcomputing.com/pipermail/pyqt/attachments/20160506/a090198f/attachment-0001.html>


More information about the PyQt mailing list