Qt wiki will be updated on October 12th 2023 starting at 11:30 AM (EEST) and the maintenance will last around 2-3 hours. During the maintenance the site will be unavailable.

Using-QtWebKit-and-QML-with-PySide: Difference between revisions

From Qt Wiki
Jump to navigation Jump to search
No edit summary
No edit summary
Line 1: Line 1:
[[Category:LanguageBindings::PySide]]<br />[[Category:Snippets]]<br />[[Category:Developing_with_Qt::Qt Quick]]<br />[[Category:Developing_with_Qt::Qt Quick::QML]]<br />[[Category:Developing_with_Qt::Qt Quick::Tutorial]]<br />[[Category:Developing_with_Qt::QtWebKit]]
[[Category:LanguageBindings::PySide]]
[[Category:Snippets]]
[[Category:Developing_with_Qt::Qt Quick]]
[[Category:Developing_with_Qt::Qt Quick::QML]]
[[Category:Developing_with_Qt::Qt Quick::Tutorial]]
[[Category:Developing_with_Qt::QtWebKit]]


[toc align_right=&quot;yes&amp;quot; depth=&quot;3&amp;quot;]
[toc align_right="yes" depth="3"]


'''English''' &quot;French&amp;quot;:http://qt-devnet.developpez.com/tutoriels/python/pyside/qml/qtwebkit/
'''English''' "French":http://qt-devnet.developpez.com/tutoriels/python/pyside/qml/qtwebkit/


= Using QtWebKit and QML with PySide =
= Using QtWebKit and QML with PySide =


This [[PySide]] tutorial shows you how to integrate Python code and [[QtWebKit]] together with QML, so you can have HTML content and program logic inside a QML application while still being able to send messages back and forth between the JavaScript context inside the WebView and the Python world. It uses JSON, alert&amp;amp;#40;&amp;#41; and evaluateJavaScript() to exchange arbitrary data structures (values, lists, dictionaries) between Python and JavaScript in the WebView.
This [[PySide]] tutorial shows you how to integrate Python code and [[QtWebKit]] together with QML, so you can have HTML content and program logic inside a QML application while still being able to send messages back and forth between the JavaScript context inside the WebView and the Python world. It uses JSON, alert() and evaluateJavaScript() to exchange arbitrary data structures (values, lists, dictionaries) between Python and JavaScript in the WebView.


== WebKitView.py ==
== WebKitView.py ==
Line 15: Line 20:
The '''sys''' module is used to get command line arguments, '''time''' is used to get the current time and '''json''' is used to en- and decode data structures to/from JSON.
The '''sys''' module is used to get command line arguments, '''time''' is used to get the current time and '''json''' is used to en- and decode data structures to/from JSON.


<code><br />import sys<br />import time<br />import json
<code>
import sys
import time
import json


from PySide import QtGui, QtDeclarative<br /></code>
from PySide import QtGui, QtDeclarative
</code>


=== Send and receive helper functions ===
=== Send and receive helper functions ===


These two functions send data to the WebView and receive data from the WebView. '''sendData''' simply transforms the data into JSON and calls '''receiveJSON''' (as defined in the HTML file) via the '''evaluateJavaScript''' method to put the data there. '''receiveData''' is connected to the '''alert''' signal of the WebView object, and gets a string as parameter, which is decoded as JSON and processed. When we want to set the rotation, we simply set the QML property &quot;rotation&amp;quot; on the WebView object, which will rotate it in our view.
These two functions send data to the WebView and receive data from the WebView. '''sendData''' simply transforms the data into JSON and calls '''receiveJSON''' (as defined in the HTML file) via the '''evaluateJavaScript''' method to put the data there. '''receiveData''' is connected to the '''alert''' signal of the WebView object, and gets a string as parameter, which is decoded as JSON and processed. When we want to set the rotation, we simply set the QML property "rotation" on the WebView object, which will rotate it in our view.


<code><br />def sendData(data):<br /> global rootObject<br /> print 'Sending data:', data<br /> json_str = json.dumps(data).replace('&quot;', '&quot;')<br /> rootObject.evaluateJavaScript('receiveJSON(&quot;s&amp;quot;)' json_str)
<code>
def sendData(data):
global rootObject
print 'Sending data:', data
json_str = json.dumps(data).replace('"', '"')
rootObject.evaluateJavaScript('receiveJSON("s")' json_str)


def receiveData(json_str):<br /> global rootObject
def receiveData(json_str):
global rootObject


data = json.loads(json_str)<br /> print 'Received data:', data
data = json.loads(json_str)
print 'Received data:', data


if len(data)  2 and data[0]  'setRotation':<br /> rootObject.setProperty('rotation', data[1])<br /> else:<br /> sendData({'Hello': 'from PySide', 'itsNow': int(time.time())})<br /></code>
if len(data)  2 and data[0]  'setRotation':
rootObject.setProperty('rotation', data[1])
else:
sendData({'Hello': 'from PySide', 'itsNow': int(time.time())})
</code>


=== Putting it all together ===
=== Putting it all together ===


Instantiate a new QApplication, a new QDeclarativeView and load the QML file. We also set the render hints to SmoothPixmapTransform, which makes the rotated WebView content look nicer (if you want more performance, remove this line). We then set the '''url''' property of our WebView to our HTML file, and finally make sure that we connect to the '''alert''' signal of the WebView, which gets emitted when the JavaScript code inside the WebView executes '''alert&amp;amp;#40;&amp;#41;'''.
Instantiate a new QApplication, a new QDeclarativeView and load the QML file. We also set the render hints to SmoothPixmapTransform, which makes the rotated WebView content look nicer (if you want more performance, remove this line). We then set the '''url''' property of our WebView to our HTML file, and finally make sure that we connect to the '''alert''' signal of the WebView, which gets emitted when the JavaScript code inside the WebView executes '''alert()'''.


<code><br />app = QtGui.QApplication(sys.argv)
<code>
app = QtGui.QApplication(sys.argv)


view = QtDeclarative.QDeclarativeView()<br />view.setRenderHints(QtGui.QPainter.SmoothPixmapTransform)<br />view.setSource(''file''.replace('.py', '.qml'))<br />rootObject = view.rootObject()<br />rootObject.setProperty('url', ''file''.replace('.py', '.html'))<br />rootObject.alert.connect(receiveData)<br />view.show()
view = QtDeclarative.QDeclarativeView()
view.setRenderHints(QtGui.QPainter.SmoothPixmapTransform)
view.setSource(''file''.replace('.py', '.qml'))
rootObject = view.rootObject()
rootObject.setProperty('url', ''file''.replace('.py', '.html'))
rootObject.alert.connect(receiveData)
view.show()


app.exec_()<br /></code>
app.exec_()
</code>


== WebKitView.qml ==
== WebKitView.qml ==
Line 45: Line 73:
This one is relatively unspectacular. Simply import QtWebKit (for this you have to install the '''libqtwebkit4-declarative''' package) and create a new WebView. The '''settings.javascriptEnabled''' part here is key - without it, JavaScript inside the WebView will not be executed.
This one is relatively unspectacular. Simply import QtWebKit (for this you have to install the '''libqtwebkit4-declarative''' package) and create a new WebView. The '''settings.javascriptEnabled''' part here is key - without it, JavaScript inside the WebView will not be executed.


<code><br />import QtWebKit 1.0
<code>
import QtWebKit 1.0


WebView { settings.javascriptEnabled: true; width: 400; height: 280 }<br /></code>
WebView { settings.javascriptEnabled: true; width: 400; height: 280 }
</code>


== WebKitView.html ==
== WebKitView.html ==
Line 55: Line 85:
Here's how we start out with the HTML file:
Here's how we start out with the HTML file:


<code><br />&amp;lt;html&amp;amp;gt;<br /> &amp;lt;head&amp;amp;gt;<br /> &amp;lt;script language=&quot;javascript&amp;quot; type=&quot;text/javascript&amp;quot;&amp;gt;<br /></code>
<code>
<html&amp;amp;gt;
<head&amp;amp;gt;
<script language="javascript" type="text/javascript">
</code>


=== JavaScript send and receive functions ===
=== JavaScript send and receive functions ===
Line 61: Line 95:
The '''sendJSON''' function will be called by our code (see below), the '''receiveJSON''' function will be called from Python by executing JavaScript code on the WebView.
The '''sendJSON''' function will be called by our code (see below), the '''receiveJSON''' function will be called from Python by executing JavaScript code on the WebView.


<code><br /> function sendJSON(data) {<br /> alert&amp;amp;#40;JSON.stringify(data&amp;amp;#41;);<br /> }<br /> function receiveJSON(data) {<br /> element = document.getElementById('received');<br /> element. innerHTML ''= &quot;&quot;'' data;<br /> }<br /></code>
<code>
function sendJSON(data) {
alert(JSON.stringify(data));
}
function receiveJSON(data) {
element = document.getElementById('received');
element. innerHTML ''= ""'' data;
}
</code>


=== Callbacks for our buttons ===
=== Callbacks for our buttons ===
Line 67: Line 109:
We'll be using the '''sendJSON''' method to send data when the buttons are clicked. Here are the functions that generate the messages and then send the data to Python:
We'll be using the '''sendJSON''' method to send data when the buttons are clicked. Here are the functions that generate the messages and then send the data to Python:


<code><br /> function setRotation() {<br /> element = document.getElementById('rotate');<br /> angle = parseInt(element.value);<br /> message = ['setRotation', angle];<br /> sendJSON(message);<br /> }<br /> function sendStuff() {<br /> sendJSON([42, 'PySide', 1.23, true, {'a':1,'b':2}]);<br /> }<br /></code>
<code>
function setRotation() {
element = document.getElementById('rotate');
angle = parseInt(element.value);
message = ['setRotation', angle];
sendJSON(message);
}
function sendStuff() {
sendJSON([42, 'PySide', 1.23, true, {'a':1,'b':2}]);
}
</code>


=== The HTML body contents ===
=== The HTML body contents ===
Line 73: Line 125:
This is the rest of the HTML file, which simply gives some text, the input field, two buttons and a preformatted text element where we will insert received stuff from Python:
This is the rest of the HTML file, which simply gives some text, the input field, two buttons and a preformatted text element where we will insert received stuff from Python:


<code><br /> &amp;lt;/script&amp;amp;gt;<br /> &amp;lt;/head&amp;amp;gt;<br /> &amp;lt;body&amp;amp;gt;<br /> &lt;h2&amp;gt;PySide + QML + WebKit FTW&amp;lt;/h2&amp;gt;<br /> &lt;p&amp;gt;<br /> Set rotation:<br /> &amp;lt;input type=&quot;text&amp;quot; size=&quot;5&amp;quot; id=&quot;rotate&amp;quot; value=&quot;10&amp;quot;/&amp;amp;gt;<br /> &lt;button onclick=setRotation()&gt;Click me now!&lt;/button&amp;gt;<br /> &lt;/p&amp;gt;<br /> &lt;p&amp;gt;<br /> Send arbitrary data structures:<br /> &lt;button onclick=sendStuff()&gt;No, click me!&lt;/button&amp;gt;<br /> &lt;/p&amp;gt;<br /> &lt;p&amp;gt;Received stuff:&lt;/p&amp;gt;<br /> &lt;pre id=&quot;received&amp;quot;&gt;&lt;/pre&amp;gt;<br /> &amp;lt;/body&amp;amp;gt;<br />&amp;lt;/html&amp;amp;gt;<br /></code>
<code>
</script&amp;amp;gt;
</head&amp;amp;gt;
<body&amp;amp;gt;
<h2>PySide + QML + WebKit FTW</h2>
<p>
Set rotation:
<input type="text" size="5" id="rotate" value="10"/&amp;amp;gt;
<button onclick=setRotation()>Click me now!</button>
</p>
<p>
Send arbitrary data structures:
<button onclick=sendStuff()>No, click me!</button>
</p>
<p>Received stuff:</p>
<pre id="received"></pre>
</body&amp;amp;gt;
</html&amp;amp;gt;
</code>


== How the example app looks like ==
== How the example app looks like ==


Once you have got all three files, start the example app like this: '''python WebKitView.py'''
Once you have got all three files, start the example app like this: '''python WebKitView.py'''

Revision as of 09:09, 25 February 2015


[toc align_right="yes" depth="3"]

English "French":http://qt-devnet.developpez.com/tutoriels/python/pyside/qml/qtwebkit/

Using QtWebKit and QML with PySide

This PySide tutorial shows you how to integrate Python code and QtWebKit together with QML, so you can have HTML content and program logic inside a QML application while still being able to send messages back and forth between the JavaScript context inside the WebView and the Python world. It uses JSON, alert() and evaluateJavaScript() to exchange arbitrary data structures (values, lists, dictionaries) between Python and JavaScript in the WebView.

WebKitView.py

Importing required modules

The sys module is used to get command line arguments, time is used to get the current time and json is used to en- and decode data structures to/from JSON.

import sys
import time
import json

from PySide import QtGui, QtDeclarative

Send and receive helper functions

These two functions send data to the WebView and receive data from the WebView. sendData simply transforms the data into JSON and calls receiveJSON (as defined in the HTML file) via the evaluateJavaScript method to put the data there. receiveData is connected to the alert signal of the WebView object, and gets a string as parameter, which is decoded as JSON and processed. When we want to set the rotation, we simply set the QML property "rotation" on the WebView object, which will rotate it in our view.

def sendData(data):
 global rootObject
 print 'Sending data:', data
 json_str = json.dumps(data).replace('"', '"')
 rootObject.evaluateJavaScript('receiveJSON("s")' json_str)

def receiveData(json_str):
 global rootObject

data = json.loads(json_str)
 print 'Received data:', data

if len(data)  2 and data[0]  'setRotation':
 rootObject.setProperty('rotation', data[1])
 else:
 sendData({'Hello': 'from PySide', 'itsNow': int(time.time())})

Putting it all together

Instantiate a new QApplication, a new QDeclarativeView and load the QML file. We also set the render hints to SmoothPixmapTransform, which makes the rotated WebView content look nicer (if you want more performance, remove this line). We then set the url property of our WebView to our HTML file, and finally make sure that we connect to the alert signal of the WebView, which gets emitted when the JavaScript code inside the WebView executes alert().

app = QtGui.QApplication(sys.argv)

view = QtDeclarative.QDeclarativeView()
view.setRenderHints(QtGui.QPainter.SmoothPixmapTransform)
view.setSource(''file''.replace('.py', '.qml'))
rootObject = view.rootObject()
rootObject.setProperty('url', ''file''.replace('.py', '.html'))
rootObject.alert.connect(receiveData)
view.show()

app.exec_()

WebKitView.qml

This one is relatively unspectacular. Simply import QtWebKit (for this you have to install the libqtwebkit4-declarative package) and create a new WebView. The settings.javascriptEnabled part here is key - without it, JavaScript inside the WebView will not be executed.

import QtWebKit 1.0

WebView { settings.javascriptEnabled: true; width: 400; height: 280 }

WebKitView.html

HTML header

Here's how we start out with the HTML file:

<html&amp;amp;gt;
 <head&amp;amp;gt;
 <script language="javascript" type="text/javascript">

JavaScript send and receive functions

The sendJSON function will be called by our code (see below), the receiveJSON function will be called from Python by executing JavaScript code on the WebView.

 function sendJSON(data) {
 alert(JSON.stringify(data));
 }
 function receiveJSON(data) {
 element = document.getElementById('received');
 element. innerHTML ''= ""'' data;
 }

Callbacks for our buttons

We'll be using the sendJSON method to send data when the buttons are clicked. Here are the functions that generate the messages and then send the data to Python:

 function setRotation() {
 element = document.getElementById('rotate');
 angle = parseInt(element.value);
 message = ['setRotation', angle];
 sendJSON(message);
 }
 function sendStuff() {
 sendJSON([42, 'PySide', 1.23, true, {'a':1,'b':2}]);
 }

The HTML body contents

This is the rest of the HTML file, which simply gives some text, the input field, two buttons and a preformatted text element where we will insert received stuff from Python:

 </script&amp;amp;gt;
 </head&amp;amp;gt;
 <body&amp;amp;gt;
 <h2>PySide + QML + WebKit FTW</h2>
 <p>
 Set rotation:
 <input type="text" size="5" id="rotate" value="10"/&amp;amp;gt;
 <button onclick=setRotation()>Click me now!</button>
 </p>
 <p>
 Send arbitrary data structures:
 <button onclick=sendStuff()>No, click me!</button>
 </p>
 <p>Received stuff:</p>
 <pre id="received"></pre>
 </body&amp;amp;gt;
</html&amp;amp;gt;

How the example app looks like

Once you have got all three files, start the example app like this: python WebKitView.py