Contact: info@riverbankcomputing.co.uk
- Version: 4.0.1
- Copyright: Copyright (c) 2006 Riverbank Computing Limited
- Traduction: Brice LEROY - bbrriiccee(at)gmail_com
Contents
Contents
Introduction
Ceci est le guide de référence pour PyQT 4.0.1. PyQT V4 est une collection de lien Python pour la V4 de la structure applicatif (framework) Qt de Trolltech.
There is a separate PyQt API Reference.
Qt est une collection de bibliothèque et d'outils de développement qui inclut une couche d'abstraction indépendante de la platforme pour l'interface graphique utilisateur, le réseau, les processus, les expressions régulières, les bases de données SQL, le SVG, l'OpenGL, le XML et les paramètres utilisateur et ceux de l'application. PyQT implémente 440 de ces classes comme une collection de module Python.
PyQT supporte les platformes Windows, Linux, Unix et MacOS/X.
PyQT n'inclut pas Qt - vous devez vous le procurer séparément.
Le site de référence pour PyQT est http://www.riverbankcomputing.co.uk/pyqt/. Ici vous pourrez toujours trouver la dernière version stable, les versions de développement courante et la dernière version de ce document (en anglais, la dernière version française sera toujours sur http://www.diotavelli.net/PyQtWiki/%5bfr%5dPythonBindingsToolsForQtV4 ).
PyQT est construit en utilisant le générateur de lien SIP. SIP doit être installé afin de pouvoir compiler et utiliser PyQT.
Les versions plus anciennes de Qt sont supportées par PyQt V4.
Licence
Comme Qt V4, PyQT est licencié sur toutes les platformes sous une licence commercial ainsi que sous la GPL v2. Votre Licence PyQT doit être la même que votre licence Qt, ex. utiliser la version commercial de chacun (PyQT et Qt) ou la licence GPL de chacun. Si vous utilisez la version GPL dans ce cas votre code devra alors être licencié sous GPL.
Vous pouvez acheter une licence commerciale ici.
Les Composants PyQt
PyQt comprend un certain nombre de composants différents. Tout d'abord il y a un certain nombre de modules d'extension de Python. Ceux-ci sont tous installés dans le paquet de Python PyQt4.
Le module QtCore. Celui-ci contient les classes coeur non IGU(Interface Graphique Utilisateur), incluant l'évènement loops, les signaux QT et le mécanisme de slot. Il inclut aussi la couche d'abstraction indépendante de la platforme pour l'Unicode, les processus, les expressions régulières et les paramètres utilisateur et applicatif.
Le module QtGui. Il contient la majorité des classes IGU.
Le module QtNetwork. Ce module contient les classes pour l'écriture de clients UDP et TCP ainsi que les serveurs. Il inclut les classes qui implémentent les clients FTP et HTTP et supporte les consultations DNS.
- Le module QtOpenGL. Ce module contient les classes qui activent l'utilisation de l'OpenGL dans le rendu de graphiques 3D au sein les applications PyQT.
Le module QtSql. Ce module contient les classes qui interagissent avec les bases SQL. Il inclut un modèle de données éditable pour les tables de base de données qui peut être utilisé avec les classes IGU. Il inclut aussi une implémentions de SQLite (NdR. moteur de bases de données relationnelles intégré).
Le module QtSvg. Ce module contient les classes pour l'affichage de contenu de fichier SVG.
Le module WtXML. Ce module contient les classes qui implémentent les interfaces SAX et DOM pour le parser (lecteur) XML de Qt.
Le module QtAssistant. Ce module contient les classes qui permettent à Qt Asssistant d'être intégré avec une application PyQt pour fournir l'aide en ligne.
- Le module Qt. Ce module consolide les classes contenues dans tous les modules décris précédemment dans un module unique. Ceci a l'avantage de ne pas avoir à se souciez de quel module sous-jacent contient une classe particulière. Il a néanmoins le désavantage de charger la totalité de la structure Qt et par conséquent d'augmenter l'empreinte mémoire d'une application. Que vous utilisiez ce module de consolidation, ou les différents modules individuels cette décision n'incombe qu'à vous même.
- Le module uic. Ce module contient les classes pour la prise en charge des fichiers .ui créés avec Qt Designer qui décrivent en totalité ou en partie l'interface graphique utilisateur. Il inclut les classes qui chargent un fichier .ui et effectuent le rendu de celui-ci directement, ainsi que les classes qui génèrent le code python à partir des .ui pour des exécutions prochaines. Il est couvert en détail dans dans le module uic.
Le module pyqtconfig est une extension du système de construction SIP et il est créé lors de la configuration de PyQT. Il en-capsule toutes les informations nécessaires à propos de votre installation Qt et permet de rendre plus simple l'écriture de scripts d'installation pour le bindings built on top of PyQt. Il est couvert en détail dans le système de construction PyQt.
PyQT contient aussi différents utilitaires.
- pyuic4 corresponds à l'utilitaire uic de Qt. Il convertit les IGU créées en utilisant Qt Designer en code python. Il est couvert en détail dans pyuic4.
- pyrcc4 corresponds à l'utilitaire rcc de Qt. Il englobe différentes ressources (comme des icônes, des images, fichiers de traduction) décrit par un fichier de collection de ressource dans un module Python. Il est couvert en détail dans pyrcc4. (Note: Il ne sera inclus que si votre copie de Qt inclut le module XML.)
- pylupdate4 correspond à l'utilitaire lupdate de Qt. Il extrait tout les chaînes de caractères traduisibles de votre code python et créé ou met à jour les fichiers de traduction .ts. Ceux-ci sont alors utilisés par Qt Linguist pour gérer les traductions de ces chaînes de caractères. Il est couvert en détail dans pylupdate4 (Note: il ne sera inclus que si votre copie de Qt inclut le module XML.)
PyQt inclut un grand nombre d'exemples. Ceux-ci sont portés en python et proviennent en grande partie des exemples fournis avec Qt. Ils peuvent être trouvés dans le répertoire exemples.
Finalement, PyQt contient les fichiers .sip utilisés par SIP pour compiler PyQt lui-même. Ils peuvent être utilisés par des développeurs de lien basé sur d'autre bibliothèques Qt - par exemple, PyQwt et PyQwt3D.(These can be used by developers of bindings of other Qt based class libraries - for example PyQwt and PyQwt3D.)
Installer PyQt
Télécharger SIP
SIP doit être installé avant de compiler et d'utiliser PyQt. Vous pouvez obtenir la dernière version du code source de SIP sur http://www.riverbankcomputing.co.uk/sip/download.php.
La documention de SIP peut être trouvée sur http://www.riverbankcomputing.com/Docs/sip4/sipref.html.
Télécharger PyQt
Vous pouvez obtenir la dernière édition de la version GPL des codes source de PyQt sur http://www.riverbankcomputing.co.uk/pyqt/download.php.
Si vous utilisez une licence commerciale de PyQt alors vous devrez télécharger les instructions qui vous ont été envoyées lorsque vous avez effectué votre achat. Vous devez de même télécharger votre fichier de licence.
Configurer PyQt
Après avoir décompressé votre paquet source (un fichier .tar.gz ou encore .zip selon votre plateforme) il vous est conseillé de consulter chaque fichier README faisant référence à votre plateforme
Si vous utilisez une version commercial de PyQt alors vous devez copier votre fichier de licence dans le répertoire sip.
Vous aurez besoin de vous assurer que vos variables d'environnements sont correctement configurées pour votre environnement de développement. Par exemple, si vous utilisez une distribution binaire de Qt sur Windows alors assurez vous d'avoir exécuté le fichier qtvars.bat. Pour les autres plateformes il est normalement suffisant de s'assurer que le répertoire binaire de Qt est dans votre PATH.
Puis vous aurez à configurer SIP en exécutant le script configure.py. Par exemple:
python configure.py
Ceci garantit que l'interpréteur est dans votre path(ndt. chemin de recherche automatique). Quelques que chose comme ce qui suit serait approprié pour les plateformes Windows :
c:\python24\python configure.py
Si vous avez plusieurs versions de Python installées alors assurez vous d'utiliser l'interpréteur avec lequel vous souhaitez compiler PyQT.
La gamme complète d'options de ligne de commande est :
Option |
Description |
-h |
Affiche le message d'aide. |
-b dir |
Les utilitaires pyuic4, pyrcc4 et pylupdate4 seront installés dans le répertoire dir. |
-c |
Les fichiers source C++ pour un module Python seront concaténés. Il en résulte une réduction significative du temps de compilation. La majorité, mais pas tous, des compilateur C++ peuvent prendre en charge le fichier de grande taille qui en résulte. Il vous est recommandé d'utiliser cette option si vous utilisez GCC v3.x ou MSVC v7.x. Voir aussi l'option -j. |
-d dir |
Les modules PyQt seront installés dans le répertoire dir. |
-i |
Le contrôle des interpréteurs signés en utilisant le paquet VendorID est activé. Voir aussi les options -l et -m et Déployer des Application PyQt Commerciales. |
-j n |
Si l'option -c est utilisée pour concaténer les fichiers source C++ alors cette option détermine combien de fichiers seront créés. Par défaut c'est 1 |
-k |
Les modules PyQT seront compilés comme des bibliothèques statiques. C'est très utile lorsque l'on construit un interpréteur 'maison' avec les modules PyQt compilés dans celui-ci. |
-l dir |
Le fichier d'entête du paquet VendorID peut être trouvé dans le répertoire dir. |
-m dir |
La bibliothèque du paquet VendorID peur être trouvé dans le répertoire dir. |
-q exe |
Le programme qmake de Qt est utilisé afin de déterminer comment votre installation Qt est disposé. Normalement qmake se trouve dans votre PATH. Cette option peut être utilisé pour spécifier un instance particulière de qmake à utiliser. |
-r |
Les modules PyQt générés contiennent des codes de traçage additionnels qui vous permettent d'utiliser la fonction sip.settracemask() de SIP. |
-u |
Les modules PyQt vont êtres compilés avec les symboles de débugage. Sur Windows cela requière qu'une version de débug de python soit installé. |
-v dir |
Les fichiers .sip pour les modules PyQt seront installés dans le répertoire dir |
-w |
Les commandes de compilation et tout autres sorties lors de la configuration seront affichées au lieu d'être supprimés. Utilisez cette option si configure.py a quelques problèmes pour voir exactement ce qui se passe mal. |
Compilation
La prochaine étape est de compiler PyQT en lançant la commande make de votre plateforme. Par exemple:
make
L'étape finale est d'installer PyQt en lançant la commande suivante :
make install
(Selon votre système, vous pouvez avoir besoin des privilèges administrateur.)
Ceci installera les différents composants PyQt.
Support des Signaux et Slots
Une des fonctions clefs de Qt est son utilisation des signaux et slots pour communiquer entre les objets. Leur utilisation encourage le développement de composants réutilisables.
Un signal est émit lorsque un évènement particulier survient. Un slot est une fonction (Dans PyQt un slot est tout élément Python appelable). Si un signal est relié à un slot (en utilisant la méthode QtCore.QObject.connect() )alors le slot est appelé lorsque le signal est émit. Si un signal n'est pas connecté alors rien ne se passe. Le code (ou le composant) qui émet le signal ne sait pas ou ne prête pas attention si le signal est utilisé.
Un signal peut être connecté à plusieurs slots.
Un signal peut être aussi connecté à un autre signal.
Un slot peut être connecté à plusieurs signaux.
En PyQt, les signaux sont émit en utilisant la méthode QtCore.QObject.emit().
Les connexions peuvent êtres directes (synchrone) ou en file d'attente (asynchrone).
Les connexions peut êtres faites à travers des processus (threads).
Les signaux sont déconnectés en utilisant la méthode QtCore.QObject.disconnect().
Signaux PyQt et Signaux Qt
Les signaux Qt sont définient statiquement comme une partie de class C++. Ils sont référencés en utilisant la fonction QtCore.SIGNAL(). Cette méthode prend une unique chaîne caratère en argument qui est le nom du signal et sa signature C++. Par exemple :
1 QtCore.SIGNAL("finished(int)")
La valeur de retour est normalement passée à la méthode QtCore.QObject.connect().
PyQt permet a de nouveaux signaux d'être définit dynamiquement. Le fait d'émettre un signal PyQt le définit implicitement. Les signaux PyQt V4 sont aussi référencé en utilisant la fonction QtCore.SIGNAL().
Signaux de court-circuit
Il y existe une forme spécial de signal PyQt V4 connus sous le nom de signal de court-circuit. Les signaux de court circuit ne peuvent être connecté uniquement qu'aux slots qui ont été implémenté en Python. Ils ne peuvent pas être connecté au slots Qt ou aux appels python qui enveloppent des slots Qt.
Les signaux de court circuit n'ont pas une liste d'arguments ou the surrounding parentheses. Leur avantage est qu'ils sont très efficaces car les arguments sont passés comme des arguments python sans aucune conversion en type de donnée C++ and back again.
Slots PyQt et Slots Qt
Les slots Qt sont définit statiquement comme une partie de classe C++. Ils sont référencés en utilisant la fonction QtCore.SLOT(). Cette méthode prend un unique argument qui est le nom du slot et sa signature C++. Par exemple :
1 QtCore.SLOT("done(int)")
La valeur retournée est normalement passé à la méthode QtCore.QObject.connect().
PyQt permet a tout élément python appelable d'être utilisé comme un slot, pas uniquement un Slot Qt. Ceci s'effectue simplement en passant en référence l'élément appelable. Parce que les slots Qt sont implémentés comme des méthodes de classe ils sont aussi disponibles comme des éléments Python appelables. Par conséquent il n'est actuellement jamais nécessaire d'utiliser QtCore.SLOT() pour des slots Qt. Cependant, le faire de cette manière est plus efficace car le signal délivre s'effectue au niveau de la couche C++ et évite toute conversion vers Python et reviens en C++.
Qt permet a un signal d'être connecté à un slot tout en exigeant moins d'arguments que le passage d'un signal(Qt allows a signal to be connected to a slot that requires fewer arguments than the signal passes). Les arguments supplémentaires sont silencieusement éliminés. Les slots PyQt peuvent être utilisés de la même façon.
Notez que lorsque un slot est un élément appelable en Python son nombre de référence n'est pas augmenté. Cela signifie qu'une instance de classe peut être supprimée sans avoir à être explicitement déconnecté de tout signaux connecté à ces méthodes. Cependant, cela signifie aussi que utiliser une expression lambda en tant que slot ne fonctionnera pas tant que vous ne gardez pas une référence séparée vers celle-ci pour éviter d'être immédiatement collecté par le Garbage Collector(ndt. déformation Java)
Connecter des Signaux et des Slots
Les connexions entre les signaux et les slots (et autres signaux) sont réalisées en utilisant la méthode QtCore.QObject.connect(). Par exemple :
1 QtCore.QObject.connect(a, QtCore.SIGNAL("QtSig()"), pyFunction)
2 QtCore.QObject.connect(a, QtCore.SIGNAL("QtSig()"), pyClass.pyMethod)
3 QtCore.QObject.connect(a, QtCore.SIGNAL("QtSig()"), QtCore.SLOT("QtSlot()"))
4 QtCore.QObject.connect(a, QtCore.SIGNAL("PySig()"), QtCore.SLOT("QtSlot()"))
5 QtCore.QObject.connect(a, QtCore.SIGNAL("PySig"), pyFunction)
Déconnecter des signaux fonctionne de la même manière via l'utilisation de la méthode QtCore.QObject.disconnect(). Cependant, toutes les variantes de cette méthode ne sont pas supporté par PyQt. Les signaux doivent être déconnectés un à la fois.
Émettre des Signaux
Toute instance de classe qui est dérivée de la classe QtCore.QObject peut émettre un signal en utilisant sa méthode emit(). Celle-ci prend un minimum d'un argument qui est le signal. Tout les autres arguments sont passés au slot connecté comme argument de signal. Par exemple :
1 a.emit(QtCore.SIGNAL("clicked()"))
2 a.emit(QtCore.SIGNAL("pySig"), "Hello", "World")
Le Decorator QtCore.pyqtSignature()
PyQt supporte la fonction QtCore.QMetaObject.connectSlotsByName() qui est plus communément utilisé par le code python généré par pyuic4 pour automatiquement connecter les signaux aux slots qui se correspondent par simple convention de nommage. Cependant, là où la classe surcharge des signaux Qt (ex. avec le même nom mais différents arguments) pyQt a besoin d'information supplémentaires afin d'automatiquement connecter le bon signal.
Par exemple la class QtGui.QSpinBox a les signaux suivant:
1 void valueChanged(int i);
2 void valueChanged(const QString &text);
Lorsque la valeur du spin box changera ces deux signaux seront émit. Si vous avez implémenté un slot appelé on_spinbox_valueChanged (ce qui signifie que vous avez donné à l'instance QSpinBox le nom spinbox) alors ce slot sera connecté aux deux variation de signal. Donc, lorsque l'utilisateur changera la valeur, votre slot sera appelé deux fois, une première fois avec un argument int (entier), et une seconde fois avec un argument QString.
Ceci arrive aussi avec des signaux qui prennent des arguments optionnels. Qt implémente cela en utilisant de multiple signaux. Par exemple, QtGui.QAbstractButton a le signal suivant :
1 void clicked(bool checked = false);
Qt implémente cela tel que ce qui suit:
1 void clicked();
2 void clicked(bool checked);
PyQt inclut une fonction Python decorator qui peut être utilisée pour indiquer lequel des signaux devrait être relié au slot. Le decorator prend une chaîne de caractère contenant la signature de signal requis, sans les parentheses. Si vous êtes uniquement intéressé par la variante entière (int) des signaux alors votre définition de slot devrait ressembler à ce qui suit :
1 @QtCore.pyqtSignature("int")
2 def on_spinbox_valueChanged(self, i):
3 # i sera un entier.
4 pass
Ce qui suit vous montre un exemple utilisant un bouton pour les cas où vous n'êtes pas intéressé par les arguments optionnels :
1 @QtCore.pyqtSignature("")
2 def on_button_clicked(self):
3 pass
Utiliser Qt Designer
Qt Designer est l'outil Qt pour dessiner et construire des interfaces graphiques utilisateur. Il vous permettra de dessiner des widgets, des boites de dialogue ou des fenêtres complètes en utilisant des formulaires on-screen et une interface simplifiée de glisser-déposer. Il a la possibilité de vous afficher une pré-visualisation de vos réalisations afin de vous assurer qu'il génère bien ce que vous escomptiez, et vous permet d'en extraire des prototypes avec vos utilisateurs ( and to allow you to prototype them with your users), avant d'avoir à écrire tout code.
Qt Designer utilise des fichiers .ui en XML pour sauvegarder vos réalisations et ne génère pas de code de lui même. Qt inclut l'utilitaire uic pour générer du code C++ qui créé l'interface utilisateur. Qt inclut aussi la class QUiLoader qui permet a une application de charger un fichier .ui et de créer l'interface correspondante dynamiquement.
PyQt n'enveloppe pas la class QUiLoader mais à la place inclut le module Python uic. Tel QUiLoader ce module peut charger des fichier .ui afin de créer une interface utilisateur dynamiquement. Comme l'utilitaire uic il peu aussi générer le code Python, qui créera l'interface utilisateur. L'utilitaire pyuic4 de PyQt est une interface en ligne de commande pour le module uic. Les deux sont décris en détail dans les sections suivantes.
Utiliser le Code Généré
Le code qui a été généré a une structure identique à celui qui est généré par Qt uic et peut être utlilisé de la même manière.
Le code est struturé dans une unique classe qui est dérivée du type object Python. Le nom de la classe est le nom de l'objet de plus haut niveau dans Designer avec le préfix Ui_. (Dans la version C++ la classe est définit dans l'espace de nom Ui.) Nous faisons référence à cette classe comme la class form.
La classe contient une méthode appelé setupUi(). Celle-ci prend un seul argument qui est le widget dans lequel l'interface utilisateur est créée. Le type de cet argument (typiquement QDialog, QWidget ou QMainWindow) est définit dans Designer. Nous faisons référence à ce type ecomme la classe Qt de base.
Dans les exemples suivants nous considérons que un fichier .ui créé contient une boite de dialogue et le nom de l'object QDialog est ImageDialog. Nous considérons aussi que le nom du fichier contenant le code généré en python est ui_imagedialog.py. Le code généré peut alors être utilisé de plusieurs manières.
Le premier exemple montre l'approche directe ou nous créons une simple application pour créer une boite de dialogue :
1 import sys
2 from PyQt4 import QtGui
3 from ui_imagedialog import Ui_ImageDialog
4
5 app = QtGui.QApplication(sys.argv)
6 window = QtGui.QDialog()
7 ui = Ui_ImageDialog()
8 ui.setupUi(window)
9
10 window.show()
11 sys.exit(app.exec_())
Le deuxième exemple montre l'approche par héritage unique ou l'on sous classe QDialog et configurons l'interface utilisateur dans la méthode init() :
1 from PyQt4 import QtCore, QtGui
2 from ui_imagedialog import Ui_ImageDialog
3
4 class ImageDialog(QtGui.QDialog):
5 def __init__(self):
6 QtGui.QDialog.__init__(self)
7
8 # Configurons l'interface utilisateur depuis Designer.
9 self.ui = Ui_ImageDialog()
10 self.ui.setupUi(self)
11
12 # Faisons quelques modifications locales.
13 self.ui.colorDepthCombo.addItem("2 colors (1 bit per pixel)")
14
15 # Connectons les boutons.
16 self.connect(self.ui.okButton, QtCore.SIGNAL("clicked()"),
17 self, QtCore.SLOT("accept()"))
18 self.connect(self.ui.cancelButton, QtCore.SIGNAL("clicked()"),
19 self, QtCore.SLOT("reject()"))
Le troisième exemple montre l'approche par héritage multiple :
1 from PyQt4 import QtCore, QtGui
2 from ui_imagedialog import Ui_ImageDialog
3
4 class ImageDialog(QtGui.QDialog, Ui_ImageDialog):
5 def __init__(self):
6 QtGui.QDialog.__init__(self)
7
8 # Configurons l'interface utilisateur depuis Designer.
9 self.setupUi(self)
10
11 # Faisons quelques modifications locales.
12 self.colorDepthCombo.addItem("2 colors (1 bit per pixel)")
13
14 # Connectons les boutons.
15 self.connect(self.okButton, QtCore.SIGNAL("clicked()"),
16 self, QtCore.SLOT("accept()"))
17 self.connect(self.cancelButton, QtCore.SIGNAL("clicked()"),
18 self, QtCore.SLOT("reject()"))
Pour une description complète voir le Manuel Qt Designer dans la documentation de Qt.
Le Module uic
Le module uic contient les fonctions suivantes :
- compileUi(uifile, pyfile, execute=False, indent=4)
- Cette fonction génère le code Python qui créera l'interface utilisateur depuis un fichier .ui Qt Designer.
uifile est un nom de fichier ou un objet de type file (ou équivalent) contenant le fichier .ui.
pyfile est un object de type file (ou équivalent) vers l'endroit ou doit être généré le code en python.
excute est optionnellement indiqué si une petite quantité de code additionnel doit être généré qui affichera l'interface utilisateur si le code est exécuté en tant qu'une application autonome.
indent est le nombre optionnel d'espace utilisé pour l'indentation du code généré. Si est égal à zéro alors le caratère tabulation sera utilisé à la place.
- loadUiType(uifile)
Cette fonctione charge un fichier .ui Qt Designer et revoie un tuple de classe form généré et la classe de base Qt. Cela peut être utilisé pour créer n'importe quel quantité d'instance de l'interface utilisateur sans avoir à parser (ndt. lire/décoder) le fichier .ui plus d'une fois.
uifile est le nom de fichier ou un objet de type file (ou équivalent) contenant le fichier .ui.
- loadUi(uifile, baseinstance=None)
- Cette fonction charge un fichier .ui Qt Designer et renvoie une instance de l'interface utilisateur.
uifile est le nom de fichier ou un objet de type file (ou équivalent) contenant le fichier .ui.
baseinstance est une instance optionnel de classe de base Qt. Si elle est spécifiée alors l'interface utilisateur y est créée. Sinon, une nouvelle instance de classe de base est automatiquement créée.
pyuic4
L'utilitaire pyuic4 est une interface en ligne de commande vers le module uic. Les commandes ont la syntax suivante :
pyuic4 [options] .ui-file
La liste complète des options de ligne de commande est :
Option |
Description |
-h, --help |
Affiche le message d'aide sur la sortie standard (stdout). |
--version |
Affiche le numéro de version sur la sortie standard (stdout) . |
-i N, --indent=N |
Le code Python est généré en utilisant une indentation de N espace. Si N est 0 alors les tabulations sont utilisé. Le défaut est de 4. |
-o FILE, --output=FILE |
Le code Python généré est écrit dans le fichier File. |
-p, --preview |
La UGI est créée dynamiquement et est affiché. Pas de code Python généré. |
-x, --execute |
Le code Python généré inclus une petite quantité de code supplémentaire qui créé et affiche l'interface graphique utilisateur(IGU) lorsqu'il est exécuté en tant qu'application autonome. |
Le PyQt Resource System
PytQt support le Qt's resource system. C'est un service pour inclure des ressources telles que des icônes et des dossiers de traduction dans une application.
PyQt supports Qt's resource system. This is a facility for embedding resources such as icons and translation files in an application. Ceci rend l'empaquetage et la distribution de ces ressources beaucoup plus simple.
Un fichier de collection de ressource .qrc est un fichier XML utilisé pour indiquer quels fichiers de ressource doivent être inclus. L'application se rapporte alors aux fichiers de ressource par leurs noms originaux mais précédés par des deux points.
Pour une description complète, incluant le format du fichier .qrc, voir The Qt Resource System dans la documentation Qt.
pyrcc4
pyrcc4 est l'équivalent PyQt de l'utilitaire Qt rcc et est utilisé exactement de la même façon. pyrcc4 lit le fichier .qrc, et les fichiers ressource, et produit un module Python qui a seulement besoin d'être importé par l'application afin pour ces ressources d'êtres disponibles comme s'ils étaient les fichiers originaux. (pyrcc4 reads the .qrc file, and the resource files, and generates a Python module that only needs to be imported by the application in order for those resources to be made available just as if they were the original files.)
Pyrcc4 ne sera inclus que si votre copie de Qt inclut le module XML.
Internationalisation des Applications PyQt
PyQt et Qt incluent un kit d'outil pour la traduction d'application vers différentes langues. Pour une description complète, voir le manuel Qt Linguist dans la documentation Qt.
Le processus d'internationalisation d'une application comprend les étapes suivantes :
- Le programmeur utilise pylupdate4 pour créer ou mettre à jour un fichier de traduction .ts pour chaque langue dans laquelle l'application doit être traduite. Un fichier .ts est un fichier XML qui contient les chaînes de caractère à traduire ainsi que les traductions correspondantes déjà effectuées. pylupdate4 peut être lancé aussi souvent que souhaité durant le développement pour mettre à jour les fichiers .ts avec les dernières chaînes de caractère à traduire.
- Le traducteur utilise Qt Linguiste pour mettre à jour les fichiers .ts avec les chaînes de caractère traduites.
- Le chef de projet utilise alors l'utilitaire lrelease de Qt pour convertir les fichiers .ts en fichiers .qm qui sont des équivalents binaires compactes utilisés par l'application. Si une application ne peut trouver un fichier .qm approprié ou une chaîne de caractère particulière non traduite, alors la chaîne de caractère utilisée dans le code source original est alors utilisé à la place.
- Le chef de projet peut optionnellement utiliser pyrcc4 pour inclure les fichiers .qm, avec d'autre ressource de l'application tel que les icônes, dans un module python. Ceci permet de rendre l'empaquetage et la distribution de l'application plus facile.
pylupdate4
pylupdate4 est l'équivalent PyQt de l'utilitaire lupdate de Qt et s'utilise de même manière. Un fichier projet Qt .pro est lu spécifiant les fichiers source Python et les fichiers d'interface de Qt Designer d'où les textes qui ont besoin d'être traduit sont extrait. Le fichier .pro spécifie aussi les fichiers de traduction .ts que pylupdate4 met à jour (ou créé si nécessaire) et est par la suite utilisé par Qt Linguist.
pylupdate4 ne sera inclus que si votre copie de Qt inclus le module XML.
Différences Entre PyQt et Qt
Qt implémente le support de l'internationalisation à travers la classe QTranslator, ets méthodes QCoreApplication::translate(), QObject::tr() and QObject::trUtf8(). Habituellement la méthode tr() est utilisée pour obtenir la traduction correcte du message. Le processus de traduction utilise un contexte de message pour permettre au même message d'être traduit différemment. tr() est actuellement généré par moc et utilise le nom de la classe en dur en tant que context. D'autre part, QApplication::translate() permet au contexte d'être explicitement énoncé.
Hélas, à cause de la manière dont Qt a implémenté tr() (et trUtf8()) il n'est pas possible pour pyQt de reproduire exactement son comportement. L'implémentation PyQt de tr() (et trUtf8()) utilise le nom de la classe de l'instance en tant que context. La différence clef, et la source potentiel de problème, est que le contexte est déterminé dynamiquement dans PyQt, mais il est codé en dur dans Qt. En d'autre termes, le contexte de la traduction peut changer selon la hiérarchie d'instance de la classe. Par exemple! :
1 class A(QtCore.QObject):
2 def hello(self):
3 return self.tr("Hello")
4
5 class B(A):
6 pass
7
8 a = A()
9 a.hello()
10
11 b = B()
12 b.hello()
Ci-dessus, le message est traduit par a.hello() en utilisant le contexte de A, et par b.hello utilisant un contexte de B. Dans une version équivalente C++ le contexte serait celui de A dans les deux cas.
Le comportement de PyQt n'est pas satisfaisant et peut changé dans le future. Il est recommandé d'utiliser de préférence QCoreApplication.translate() plutot que tr() (et trUtf8()). Cet méthode est garantie fonctionnel avec les versions courantes et futures de PyQt et permet de rendre plus simple le partage de fichiers de message entre Python et le code C++. Voyez ci-dessous une implémentation alternative de A utilisant la fonction QCoreApplication.translate():
1 class A(QtCore.QObject):
2 def hello(self):
3 return QtCore.QCoreApplication.translate("A", "Hello")
Choses à savoir
Les Chaînes de Caractère Python , Les Chaînes de Caractère Qt et Unicode
Le support Unicode a été ajouté à Qt à la version 2.0 et à Python dans la version 1.6. Dans Qt, le support Unicode est implémenté en utilisant la classe QString. Il est important de comprendre que les instances QString, les chaînes de caractère Python et les objets Python Unicode sont totalement différent mais que les conversions entre-eux sont automatique dans la majorité des cas et qu'il est simple de les convertir manuellement lorsque nécessaire.
Lorsque PyQt attend une QString en argument de fonction, un objet chaîne de caractère Python ou un objet Unicode Python peut être fournis à la place, et PyQt fera la conversion nécessaire automatiquement.
Vous pouvez aussi convertir manuellement une chaîne de caractère Python et un objet Unicode en instance QString en utilisant le constructeur QString tel qu'exposé dans l'extrait suivant :
1 qs1 = QtCore.QString("Converted Python string object")
2 qs2 = QtCore.QString(u"Converted Python Unicode object")
De façon a convertir un QString vers un objet chaîne de caractère python utilisez la méthode native str(). Appliquer str() sur un objet QString nul et un objet QString vide résultera dans les deux cas en une chaîne de caractère Python vide.
Afin de convertir un QString vers un objet Python Unicode utilisez la méthode native Python unicode(). Appliquer unicode() sur un objet QString nul et un objet QString vide résultera dans les deux cas en une chaîne de caractère Python vide.
QString implémente aussi le protocole de mise en tampon de Python qui signifie qu'une QString peut être utilisé dans beaucoup de cas ou une chaîne de caractère Python ou un objet Unicode est attendu sans être explicitement convertis.
Garbage Collection - Ramasse miette
C++ ne récupère pas dans son ramasse miette les classes d'instances non référencées, là ou Python le fait. Dans le l'extrait de code suivent les deux couleurs existent bien que la première ne puisse plus être référencée au sein du programme :
col = new QColor(); col = new QColor();
Dans l'extrait correspondant en Python, la première couleur est détruite lorsque la deuxième est assigné à col :
1 col = QtGui.QColor()
2 col = QtGui.QColor()
En Python, chaque couleur doit être assignée à différent nom. Typiquement ceci est fait au sein de la définition de classe, ainsi l'extrait de code devrait ressembler à ce qui suit :
1 self.col1 = QtGui.QColor()
2 self.col2 = QtGui.QColor()
Parfois une instance de classe Qt maintiendra un pointeur vers une autre instance et appellera éventuellement le destructeur de cette seconde instance. L'exemple le plus courant est qu'un QObject (et de ces sous classes) garde le pointeur sur ces enfants et ira automatiquement appeler leur destructeur. Dans ces cas, l'objet Python correspondant conservera lui aussi une référence vers ces objets enfants correspondant.
Ansi, dans l'extrait Python suivant, le premier QLabel n'est pas détruit lorsque le second est assigné à lab car le QWidget parent conserver une référence vers celui-ci :
1 parent = QtGui.QWidget()
2 lab = QtGui.QLabel("First label", parent)
3 lab = QtGui.QLabel("Second label", parent)
Héritage Multiple
Il n'est pas possible de définir une nouvelle classe Python qui hérite de plus d'une classe Qt.
Accès aux Fonctions Membres Protégées
Lorsqu'une instance de classe C++ n'est pas créé à partir de Python il n'est pas possible d'accéder aux fonctions membres protégées, ou émettre tous signaux, de cette instance. Le tenter leverait alors une exception Python. En outre, toute méthodes Python correspondant à l'instance d'une fonction membre virtuelle ne sera jamais appelée.
None and NULL
Dans tout PyQt, la valeur None peut être spécifiée partout où NULL est accepté dans le code C++.
Également, Null est convertis en None partout ou il est renvoyé par le code C++.
Support de void *
PyQt (acuellement SIP) représente la valeur void * comme un objet de type sip.voidptr. De telles valeurs sont souvent utilisées pour passer l'adresse d'objet externe entre différents modules Python. Pour rendre cela plus simple, un entier Python (ou tout ce que python peut convertir en entier) peut être utilisé partout ou sip.voidptr est attendue.
Un sip.voidptr peut être convertis vers un entier Python en utilisant la méthode native int().
Un sip.voidprt peut être convertis vert une chaîne de caractère Python par l'utilisation de la méthode asstring(). La méthode asstring() prend un argument entier qui est la longueur des données en bytes.
super et les Classes PyQt
PyQt implémente en interne une technique paraisseuse (Lazy Technique) pour la consultation d'attributs où les attributs sont toujours placés dans des type et des dictionnaires d'instance lorsqu'ils sont référencés en premier. Cette technique est nécessaire pour réduire le temps pris par l'importation de large modules tel que PyQt.
Dans la majorité des cas cette technique est transparente pour une application. L'exception apparaît lorsque super est utilisé avec une classe PyQt. La manière dont super est aujourd'hui implémenté implique que la consulation paresseuse est outre passée. Il en résulte une exception AttributeError tant que les attributs n'ont pas été référencés auparavant.
Notez que cette restriction s'applique à toute classe enveloppée par SIP pas uniquement PyQt.
Déployer des Applications Commerciales PyQt
Lors du déploiement d'application commerciales PyQt il est nécessaire de décourager les utilisateurs d'accéder aux modules fondamentaux de PyQt pour eux-mêmes. En effet, un utilisateur qui se sert des modules apportés avec votre application pour développer de nouvelles applications sera lui aussi considéré comme un développeur et devra acquérir sa propre licence Qt et PyQt.
Une solution à ce problème est le paquet VendorID. Celui-ci vous permet de construire un module d'extension Python qui ne peut être importé que par un interpréteur signé numériquement. Le paquet vous permet de créer un tel interpréteur avec votre application au sein de celui-ci. Le résultat est un interpréteur qui ne peut que lancer votre application, et des modules PyQt qui ne peuvent uniquement être importés par cet interpréteur. Vous pouvez utiliser le paquet de façon similaire pour restreindre l'accès à tout module d'extension.
Afin de compiler PyQt avec le support du paquet VendorID, passer l'instruction -i à configure.py.
Le Système de Compilation PyQt
Le système de compilation PyQt est une extension du système de compilation SIP et est implémenté par le module pyqtconfig, une partie du paquet PyQt4. Il peut être utilisé par des scripts de configuration d'autre liens qui compilent sur PyQt et prêtent attention aux détails de l'installation Qt (It can be used by configuration scripts of other bindings that build on top of PyQt and takes care of the details of the Qt installation.).
Le module contient un certain nombre de classes.
Les Classes pyqtconfig
- Configuration(sipconfig.Configuration)
- Cette classe encapsule les valeurs de configuration qui peuvent êtres accédées comme instance d'objets.
- Les valeurs de configuration suivantes sont fournis en supplément de celles fournis par la super classe :
- pyqt_bin_dir
Le nom du répertoire ou les utilitaires PyQt sont installés.
- pyqt_config_args
La ligne de commande passé à configure.py lorsque PyQt avait été configuré.
- pyqt_mod_dir
Le nom du répertoire ou le paquet PyQt4 est installé.
- pyqt_modules
Une chaîne de caractère séparée par des espaces répertoriant la liste des modules PyQt installés. Le module Qt n'est pas inclus.
- pyqt_sip_dir
Le nom du répertoire de base ou les fichiers PyQt .sip sont installés. Chaque fichier module .sip est installé dans un sous-répertoire avec le même nom que le module.
- pyqt_sip_flags
Une chaîne de caractère séparée par des espaces répertoriant la liste des arguments de ligne de commande utilisés pour compiler les modules Pyqt. Ceux-ci devraient eux aussi être utilisés lors de liasions qui importent tout modules PyQt(These should also be used when building bindings that %Import any PyQt modules.).
- pyqt_version
La version de PyQt en 3 parties hexadécimale (ex. V4.0.1 est représenté 0x040001).
- pyqt_version_str
La version de PyQt en chaîne de caractère. Pour les éditions de développement elle commencera par snapshot-.
- qt_data_dir
La valeur de QLibraryInfo::location(DataPath) pour l'installation de Qt.
- qt_dir
- Le répertoire de base de l'installation de Qt (normalement le répertoire qui contient le répertoire bin)
- qt_edition
- L'édition de Qt.
- qt_framework
- Renseigné si Qt est compilé en tant que structure applicatif MaxOS/X.
- qt_inc_dir
La valeur de QLibraryInfo::location(HeadersPath) pour l'installation de Qt.
- qt_lib_dir
La valeur de QLibraryInfo::location(LibrariesPath) pour l'installation de Qt.
- qt_threaded
Renseigné si Qt est compilé avec le support des processus (thread support) (toujours renseigné pour PyQt).
- qt_version
- La version Qt en 3 parties hexadécimale (ex. v4.1.2 est représenté 0x040102).
- qt_winconfig
- Détail de Configuration supplémentaire propre à Windows.
- __init__(self, sub_cfg=None)
- Initialise l' instance.
sub_cfg est une liste optionnel de configurations de sous-classe. Elle doit être utilisé par la méthode init() d'une sous classe pour l'ajouter à son dictionnaire de valeur de configuration avant de passer la liste à sa super-classe.
- Les valeurs de configuration suivantes sont fournis en supplément de celles fournis par la super classe :
- QtAssistantModuleMakefile(QtNetworkModuleMakefile)
Cette classe en-capsule un Makefile pour compiler un module d'extension SIP qui est compilé sur le module PyQt QtAssistant.
- QtCoreModuleMakefile(sipconfig.SIPModuleMakefile)
Cette classe en-capsule un Makefile pour compiler un module d'extension SIP qui est compilé sur le module PyQt QtCore.
- QtGuiModuleMakefile(QtCoreModuleMakefile)
Cette classe en-capsule un Makefile pour compiler un module d'extension SIP qui est compilé sur le module PyQt QtGui.
- QtNetworkModuleMakefile(QtCoreModuleMakefile)
Cette classe en-capsule un Makefile pour compiler un module d'extension SIP qui est compilé sur le module PyQt QtNetwork.
- QtOpenGLModuleMakefile(QtGuiModuleMakefile)
Cette classe en-capsule un Makefile pour compiler un module d'extension SIP qui est compilé sur le module PyQt QtOpenGL.
- QtSqlModuleMakefile(QtGuiModuleMakefile)
Cette classe en-capsule un Makefile pour compiler un module d'extension SIP qui est compilé sur le module PyQt QtSql.
- QtSvgModuleMakefile(QtGuiModuleMakefile)
Cette classe en-capsule un Makefile pour compiler un module d'extension SIP qui est compilé sur le module PyQt QtSvg.
- QtXmlModuleMakefile(QtCoreModuleMakefile)
Cette classe en-capsule un Makefile pour compiler un module d'extension SIP qui est compilé sur le module PyQt QtXml.
PyQt Wiki