PySide: QWebPage.isModified() is out of sync
-
I'm trying to detect form GET/POST in a QWebView. here's a working sample:
@from PySide.QtGui import QMainWindow, QLineEdit, QLabel, QVBoxLayout, QGridLayout, QApplication, QWidget
from PySide.QtCore import QUrl
from PySide.QtWebKit import QWebView
import sysclass Window(QMainWindow):
def init(self, parent=None):
super(Window, self).init(parent)
layout = QVBoxLayout()
self.browser = QWebView()
self.browser.setUrl(QUrl("http://www.google.com"))
self.browser.page().loadStarted.connect(self._printFormParams)
layout.addWidget(self.browser)
self.form_layout = QGridLayout()
layout.addLayout(self.form_layout)
layout_widget = QWidget()
layout_widget.setLayout(layout)
self.setCentralWidget(layout_widget)def _printFormParams(self):
page = self.browser.page()
frame = page.mainFrame()
url = frame.url()
self.lineedit_search.setText(url.toString())
if page.isModified():
form = frame.findFirstElement("form")
if not form.isNull(): # there's a form that might have been populated
texts = form.findAll("input[type='text']")
radios = form.findAll("input[type='radio']")
selects = form.findAll("select")
checkboxes = form.findAll("input[type='checkbox']")
collections = [texts, radios, selects, checkboxes]
for col in collections:
for elem in col:
print "Name: {}, Value: {}".format(elem.attribute("name"), elem.attribute("value"))
@
So I'm trying to detect the form changes when the user navigates away from it, in the page's loadStarted handler.
Here's the problem: the web view opens up to google.com. I type a query in the box (say foo) and hit enter. the isModified() call in line 25 doesn't succeed. Then I type another query (say bar) and hit enter. now, the isModified() call succeeds, and it prints "Name: q, Value: foo", which is the previous query.
If I continue to type queries, the pattern continues and I'm out of sync by one step.
Am I doing something wrong here?. -
You may notice from the example that the forms I care to detect are not mine.
Here's another couple of ways I tried to do the same thing (catching forms):
1- Attach onsubmit javascript handler on the form (this doesn't respond at all):
@def _integrateForms(self, ok):this is the page's loadFinished handler
if ok: page = self.browser.page() frame = page.mainFrame() frame.addToJavaScriptWindowObject("reporter", self) form = frame.findFirstElement("form") form_onsubmit = form.attribute("onsubmit") new_onsubmit = "reporter.submitPerformed(this.elements);" + form_onsubmit form.setAttribute("onsubmit", new_onsubmit)
def submitPerformed(self, values):
print values@2- Evaluate javascript on the form on the page's loadStarted event:
@def loadStartedHandler(self):
page = self.browser.page()
frame = page.mainFrame()
form = frame.findFirstElement("form")
values = form.evaluateJavaScript("""
var ret = {};
var unwanted_inputs = ["submit"];
for (var i = 0; i < this.length; ++i) {
elem = this.elements[i];
// do not include hidden elements neither submit buttons
if ( elem.offsetParent !== null && unwanted_inputs.indexOf(elem.type) === -1 )
ret[elem.name] = elem.value;
}
ret;
""")
print "Values: {}".format(values)@
This last one seems to work, with some extra outputs.