Search code examples
javascriptpythonqtpysideqwebkit

QtWebKit bridge: call JavaScript functions


I am writing a hybrid application with HTML interface and Python code. I can access Python functions via a shared object:

pythonPart.py:

class BO(QObject):
    def __init__(self, parent=None):
        super(BO, self).__init__(parent)

    @Slot(str)
    def doStuff(self, txt):
        print(txt)

bridgeObj = BO()

# init stuff and frame...
frame.addToJavaScriptWindowObject( 'pyBridge', bridgeObj )
frame.evaluateJavaScript('alert("Alert from Python")')
frame.evaluateJavaScript('testMe()')
frame.evaluateJavaScript('alert("Starting test");testMe();alert("Test over")')

jsPart.js:

function testMe() { alert('js function testMe called'); }

pyBridge.doStuff("bla");
testMe();

Calling Python functions from JS works, as does calling testMe from JS. Calling "standard" JS functions like alert from Python works, too.

The last two Python lines won't: evaluateJavaScript("testMe()") doesn't do anything at all. The last line executes the first alert and won't continue after that.

EDIT: I already tried having some time.sleep() between loading and calling the evaluateJavaScript and I'm loading the webpage from the local machine.


Solution

  • The most likely problem is that the JavaScript just isn't loaded yet. Adding time.sleep() calls doesn't help for that, those will also block the Qt event loop from continuing, not just your Python code.

    Try waiting for the page to have fully loaded instead, for example (using the loadFinished signal:

    def onLoad():
        frame.evaluateJavaScript('testMe()')
    
    frame.loadFinished.connect(onLoad)
    

    Aditionally, for getting more debug information in situations like this, you might want to implement QtWebKit.QWebPage.javaScriptConsoleMessage.