Saturday, January 16, 2010

Calling Python from JavaScript in PyQt's QWebkit

QtWebKit makes it very easy to expose methods and properties implemented in Python to JavaScript. Qt will automatically expose Qt-slots and Qt-properties to a JavaScript when a QObject is made available in the frame's JavaScript context.

I think the code speaks for itself
import sys
from PyQt4 import QtCore, QtGui, QtWebKit

"""Html snippet."""
html = """
  <script language="JavaScript">
    document.write('<p>Python ' + pyObj.pyVersion + '</p>')
  <button onClick="pyObj.showMessage('Hello from WebKit')">Press me</button>

class StupidClass(QtCore.QObject):
    """Simple class with one slot and one read-only property."""

    def showMessage(self, msg):
        """Open a message box and display the specified message."""
        QtGui.QMessageBox.information(None, "Info", msg)

    def _pyVersion(self):
        """Return the Python version."""
        return sys.version

    """Python interpreter version property."""
    pyVersion = QtCore.pyqtProperty(str, fget=_pyVersion)

def main():
    app = QtGui.QApplication(sys.argv)

    myObj = StupidClass()

    webView = QtWebKit.QWebView()
    # Make myObj exposed as JavaScript object named 'pyObj'"pyObj", myObj)

    window = QtGui.QMainWindow()


if __name__ == "__main__":
Some references:


  1. A minor thing to note is that you should ensure you re-add your object to the window every time the javaScriptWindowObjectCleared() signal is emitted too. There's a C++ example of this on my blog post

  2. Wow! I've been looking for a way to do this for a week straight! This is miles ahead of anything I was able to find for Python-Gobject. And it's from 2010, good lord...

  3. All the day with "Python-Gobject" search too, reading c++ code, and here is! clear and well commented code! Thank you!!!

  4. You're welcome! Glad I can help

  5. Is there anyway to connect with an onItemClick in a loaded .js file? It seems not to work when the code is loaded from a .js on disk.

  6. Sorry, don't know. Haven't been playing anymore with this in years.