0

I have a problem with PyQt/its Webview. The code that is bothering me should render a chart, but it doesn't. I am using the Highcharts framework and provide the data for the javascript function that renders the chart via Python. I also check whether the webview is ready because that was a previous error of mine. The code in question looks something like this:

command = ('loadPinch(' + str(random.sample(range(10000), 1000)) +
            ', ' + str(['2009', '01', '01']) + ');')
self.webview.page().mainFrame().evaluateJavaScript("""
        var readyStateCheckInterval = setInterval(function() {
            if(document.readyState === 'complete'){ """ +
                command + """
                clearInterval(readyStateCheckInterval);
            }
        }, 10);""")

loadPinch is a JavaScript function and looks similar to this(which in turn looks similar to a Highcharts example graph):

    function loadPinch(data, date){
    $('#container').highcharts({
        chart: {
            zoomType: 'x',
            spacingRight: 20
        },
        title: {text: 'Twitter Trends'},
        subtitle: {
            text: document.ontouchstart === undefined ?
                'Click and drag in the plot area to zoom in' :
                'Pinch the chart to zoom in'
        },
        xAxis: {
            type: 'datetime',
            maxZoom: 10 * 24 * 3600000,
            title: {text: null}
        },
        yAxis: {
            title: {text: 'Occurence'}
        },
        tooltip: {shared: true},
        legend: {enabled: false},
        plotOptions: {
            area: {
                fillColor: {
                    linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1},
                    stops: [
                        [0, Highcharts.getOptions().colors[0]],
                        [1, Highcharts.Color(Highcharts.getOptions().colors[0]).setOpacity(0).get('rgba')]
                    ]
                },
                lineWidth: 1,
                marker: {enabled: false},
                shadow: false,
                states: {hover: {lineWidth: 1}},
                threshold: null
            }
        },
        series: [{
            type: 'area',
            name: 'Twitter Trend',
            pointInterval: 24 * 3600 * 1000,
            pointStart: Date.UTC(date[0], date[1], date[2]),
            data: data
        }]
    });
};

I might tell you that if I print the command that I am handing evaluateJavaScript to the console instead of executing it and pasting it over to the developer console, it gets executed as expected and renders the chart which leads me to believe that there is some sort of race condition I can't track down.

Does someone have an idea of what could be the problem?

Regards, Carson

NOTE: The problem is still relevant.

9
  • Do you have any errors in JavaScript console? Could you post generated code in browser by your python code? Commented May 13, 2014 at 12:27
  • There are no errors. The variable readyStateCheckInterval exists, though. The generated code looks similar to this(although the data part is longer): pastebin.com/yZ9H6zfD Commented May 15, 2014 at 15:23
  • Then it looks like evaluateJavaScript doesn't work as you expect. Unfortunatetly I'm not any kind of expert with webView, however, have you tried this solutions? Commented May 16, 2014 at 13:29
  • That is a different evaluateJavascript function sadly(mine is qt, not android). i will be reading a bit info from the docs. Commented May 20, 2014 at 10:44
  • 1
    after a few tries i managed to solve the problem pretty easily. qt has a loadFinished signal which i just bound to my plot-method. now it works like a charm. Seems like before the site is loaded completely, you cannot add to the JavaScript. Commented May 27, 2014 at 16:59

1 Answer 1

5

I eventually found my fix; i thought too much in JS terms.

There is a signal in QT that is emitted when the page is finished loading, called loadFinished(). By binding this signal to a slot of mine which executed the call to evaluateJavascript(command), the chart loaded. It seems like Qts webview has problems to execute Javascript when the page hasn't finished loading yet.

Anyway, this is how the code looks like(simplified):

class something():
    def __init__(self):
        self.webview = QtWebkitWidgets.QWebView()
        self._myBindingFunction()

    def _myBindingFunction(self):
        self.webview.loadFinished.connect(self._plot)

    def _plot(self):
        command = ('loadPinch(' + str(random.sample(range(10000), 1000)) +
                   ', ' + str(['2009', '01', '01']) + ');')
        self.webview.page().mainFrame().evaluateJavaScript(command)

Note how that simplifies the JS code; i do not have to check for the site having loaded, because after the signal is emitted, it has to be ready.

Big shoutout to Pawel Fus though for leading me onto the right track. I was already giving it up.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.