Utiliser QML et QtWebKit avec PySide

| traducteur : Thibaut Cuvelier | Qt Developer Network |

Ce tutoriel sur PySide montre comment intégrer du code Python et QtWebKit avec QML. Le résultat sera un contenu HTML et une logique dans une application QML, tout en pouvant envoyer des messages entre le contexte JavaScript de la QWebView et le monde Python. On utilisera JSON, alert() et evaluateJavaScript() pour échanger des structures de données arbitraires (valeurs, listes, dictionnaires) entre Python et JavaScript dans la QWebView.

Commentez !

- Titre : Utiliser QML et QtWebKit avec PySide

- Auteurs : traducteur : Thibaut Cuvelier, Qt Developer Network

- Parution : 14 janvier 2011

- Mise à jour : 28 avril 2011

- Licence : Creative Commons Attribution-ShareAlike 2.5 Generic

Sommaire

- I. L'article original

- II. WebKitView.py

- II-A. Importer les modules requis

- II-B. Fonctions d'envoi et de réception

- II-C. Le tout mis ensemble

- III. WebKitView.qml

- IV. WebKitView.html

- IV-A. En-tête HTML

- IV-B. Envoi JavaScript et fonctions de réception

- IV-C. Fonctions de rappel pour les boutons

- IV-D. Contenu du fichier HTML

- V. Conclusion

I - L'article original

Le Qt Developer Network est un réseau de développeurs utilisant Qt afin de partager leur savoir sur ce framework. Vous pouvez le consulter en anglais.

Nokia, Qt, Qt Quarterly et leurs logos sont des marques déposées de Nokia Corporation en Finlande et/ou dans les autres pays. Les autres marques déposées sont détenues par leurs propriétaires respectifs.

Cet article est la traduction de Using QtWebKit and QML with PySide.

II - WebKitView.py

II-A - Importer les modules requis

Le module sys est utilisé pour récupérer les arguments en ligne de commande ; time, pour l'heure courante ; json, pour coder et décoder des structures de données en JSON.

import sys
import time
import json

from PySide import QtGui, QtDeclarative

II-B - Fonctions d'envoi et de réception

Ces deux fonctions envoient des données à la WebView et en reçoivent. sendData transforme simplement les données en JSON et appelle receiveJSON, telle que définie dans le fichier HTML, via la méthode evaluateJavaScript. receiveData est connectée au signal d'alerte de l'objet WebView et reçoit une chaîne de caractères en paramètre, qui est décodée comme étant du JSON puis traitée. Quand on veut une rotation, on utilise simplement la propriété rotation en QML sur l'objet WebView, ce qui provoque la rotation dans la vue.

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())})

II-C - Le tout mis ensemble

On instancie une nouvelle QApplication, une QDeclarativeView et on y charge le fichier QML. On définit aussi les indices de rendu à SmoothPixmapTransform, ce qui rend la rotation de WebView plus belle, au détriment des performances. Ensuite, on définit la propriété url de la WebView au fichier HTML et, finalement, on s'assure qu'elle est connectée au signal d'alerte de la WebView, qui est émis quand le code JavaScipt dans la WebView exécute la méthode 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_()

III - WebKitView.qml

Cette partie est particulièrement peu spectaculaire. On importe simplement QtWebKit (pour ceci, il faut avoir installé le paquet libqtwebkit4-declarative) et on crée une nouvelle WebView. La partie settings.javascriptEnabled joue un rôle très important ici : sans elle, le JavaScript dans la WebView ne serait pas exécuté.

import QtWebKit 1.0

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

IV - WebKitView.html

IV-A - En-tête HTML

Voici le début de notre fichier HTML :

<html>
<head>
[removed]

IV-B - Envoi JavaScript et fonctions de réception

La fonction sendJSON sera appelée par le code (voir plus bas) ; la fonction receiveJSON sera appelée par Python en exécutant du code JavaScript dans la WebView.

function sendJSON(data) {
alert(JSON.stringify(data));
}
function receiveJSON(data) {
element = document.getElementById('received');
element[removed] += "\n" + data;
}

IV-C - Fonctions de rappel pour les boutons

On utilise la méthode sendJSON pour envoyer des données quand les boutons sont cliqués. Voici les foncions qui génèrent les messages et envoient des données à 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}]);
}

IV-D - Contenu du fichier HTML

Voici le reste du fichier HTML, qui donne juste un peu de texte, le champ d'entrée, deux boutons et un élément de texte préformaté où seront insérées les données reçues de Python :

[removed]
</head>
<body>
<h2>PySide + QML + WebKit FTW</h2>
<p>
Set rotation:
<input type="text" size="5" id="rotate" value="10"/>
<button>Click me now!</button>
</p>
<p>
Send arbitrary data structures:
<button>No, click me!</button>
</p>
<p>Received stuff:</p>
<pre id="received"></pre>
</body>
</html>

V - Conclusion

Voici ce à quoi ressemble l'application, une fois les trois fichiers installés :

Merci à U. Milité et à Claude Leloup pour leur relecture !