I would like to thank Rich Moore for commenting on the previous post and pointing out that you should re-add your python object every time the javaScriptWindowObjectCleared() signal is emitted.
Actually, I think this is almost to simple to do a post about so I'll try doing something fun/useful with it.
QWebFrame contains a public slot:
QVariant evaluateJavaScript(const QString & scriptSource)You simply pass the JavaScript-snippet to the function. The snippet will be evaluated using the frame as context and returns the result of the last executed statement. This makes it possible to 'click' submit buttons, fill form fields and other interesting stuff in the currently loaded frame. I'll give you an example on how you can create an auto-login GMail widget. The widget will automatically login the user by populating the login form with the user's credentials and 'click' the login button.
#!/usr/bin/env python from PyQt4 import QtCore from PyQt4 import QtGui from PyQt4 import QtWebKit javaScriptLogin = """ document.getElementsByName('Email').item(0).value='{email}'; document.getElementsByName('Passwd').item(0).value='{password}'; document.getElementsByName('signIn').item(0).click(); void(0); """ class GmailWebView(QtWebKit.QWebView): def __init__(self, parent=None): super(GmailWebView, self).__init__(parent) self.loggedIn = False def login(self, url, email, password): """Login to gmail.""" self.url = QtCore.QUrl(url) self.email = email self.password = password self.loadFinished.connect(self._loadFinished) self.load(self.url) def createWindow(self, windowType): """Load links in the same web-view.""" return self def _loadFinished(self): if self.loggedIn: self.loadFinished.disconnect(self._loadFinished) self.loggedIn = True jscript = javaScriptLogin.format(email=self.email, password=self.password) self.page().mainFrame().evaluateJavaScript(jscript) def contextMenuEvent(self, event): """Add a 'Back to GMail' entry.""" menu = self.page().createStandardContextMenu() menu.addSeparator() action = menu.addAction('Back to GMail') @action.triggered.connect def backToGMail(): self.load(self.url) menu.exec_(QtGui.QCursor.pos()) def main(): import sys qApp = QtGui.QApplication(sys.argv) # Prevents me from posting my password on the blog :) password, ok = QtGui.QInputDialog.getText(None, "Password request", "Enter password", QtGui.QLineEdit.Password) if not ok: return gmailWebView = GmailWebView() gmailWebView.login('https://mail.google.com/mail', 'mario.boikov', password) gmailWebView.show() sys.exit(qApp.exec_()) if __name__ == "__main__": main()
This is just a quick hack, it lacks a bunch of checkings...
Maybe it's time to wipe the dust off my GMonitor-plasmoid and add support for opening my account in a new window based on the GMail widget above.