I have some problems observing event-propertys of html elements in a QWebpage with pyqt. The webpage I want to load and execute with pyqt:
<html>
<head>
<title>Test</title>
<script>
/*
* object.watch polyfill
*
* 2012-04-03
*
* By Eli Grey, http://eligrey.com
* Public Domain.
* NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
*/
// object.watch
if (!Object.prototype.watch) {
console.log("Watch defined...")
Object.defineProperty(Object.prototype, "watch", {
enumerable : false,
configurable : true,
writable : true,
value : function(prop, handler) {
var oldval = this[prop], newval = oldval, getter = function() {
return newval;
}, setter = function(val) {
console.log("Set: " + prop);
oldval = newval;
return newval = handler.call(this, prop, oldval, val);
};
console.log("Before if statement...")
if (true) { //here in original code is: "delete this[prop]", in every browser it is true but in a QWebpage not... why?
console.log("After if statement: " + prop
+ " is observed...")
Object.defineProperty(this, prop, {
enumerable : true,
configurable : true,
get : getter,
set : function(val) {
console.log("Set: " + prop)
oldval = newval;
var newval = handler.call(this, prop, oldval, val)
|| val;
return newval;
}
});
} else {
console.log("Error: can't be observed")
}
}
});
}
// object.unwatch
if (!Object.prototype.unwatch) {
Object.defineProperty(Object.prototype, "unwatch", {
enumerable : false,
configurable : true,
writable : false,
value : function(prop) {
var val = this[prop];
delete this[prop]; // remove accessors
this[prop] = val;
}
});
}
</script>
</head>
<body>
<div id="target" href="#">LINK WITH HANDLER</div>
<script>
link = document.getElementById("target");
//
//link.onclick = myClick2
link.watch("onclick", function(prop, oldVal, newVal) {
console.log("watch > onclick has changed!!");
return newVal;
});
link.onclick = myClick;
function myClick(e) {
console.log("Dear sir, here is a click");
}
</script>
When I'm putting that in a html-page and execute it on a browser(Chrome, Firefox, Epiphany, ...) I get the desired behaviour and could read the console log message.
But when I'm trying to load the page with QWebpage in python with pyqt4(I also tried pyqt5) then the page doesn't behave in the same way. After some tests, I noticed the problem is in the if-statement. In every browser it is true, in contrast using QWebpage. When I'm deleting it, then I get the error message from the headline.
Can someone please tell me why this is so and what is the different in a webpage rendered with QWebpage and a normal browser using the same JavaScript engine? I hope I give enough information. Thank you for your help!
Here is the code to fetch the html page:
import sys
import logging
from PyQt4.QtWebKit import QWebPage
from time import time, sleep
from PyQt4.QtCore import QUrl
from PyQt4.Qt import QApplication
class Browser(QWebPage):
def __init__(self, app, proxy = "", port = 0):
QWebPage.__init__(self)
self.loadFinished.connect(self._loadFinished)
self.app = app
def get(self, requested_url, timeout=20):
logging.debug("Browser started on {}...".format(requested_url))
self._loading_complete = False
self.mainFrame().load(QUrl(requested_url))
t = 0
while(not self._loading_complete and t < timeout ): # Waiting for finish processing
self._wait(0.1)
t += 0.1
if not self._loading_complete:
logging.debug("Timeout Occurs")
self._analyzing_finished = True
return self.mainFrame().toHtml()
def _loadFinished(self, result):
if result:
self._loading_complete = True
def _wait(self, waittime=1):
"""Wait for delay time
"""
deadline = time() + waittime
while time() < deadline:
sleep(0)
self.app.processEvents()
def javaScriptConsoleMessage(self, message, lineNumber, sourceID):
logging.debug("Console: " + message + " at: " + str(lineNumber))
if __name__ == '__main__':
logging.basicConfig(level=logging.DEBUG,
format='%(asctime)s: %(levelname)s - %(message)s',
datefmt='%d.%m.%Y %H:%M:%S',
#filename='Crawler.log',
#filemode='w'
)
app = QApplication(sys.argv)
browser = Browser(app)
browser.get("http://localhost/") #Console output is important