1. Page d'accueil

Python Bindings Tools For QtV4

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 :

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 :

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 :

QtCore.QObject.connect(a, QtCore.SIGNAL("QtSig()"), pyFunction)
QtCore.QObject.connect(a, QtCore.SIGNAL("QtSig()"), pyClass.pyMethod)
QtCore.QObject.connect(a, QtCore.SIGNAL("QtSig()"), QtCore.SLOT("QtSlot()"))
QtCore.QObject.connect(a, QtCore.SIGNAL("PySig()"), QtCore.SLOT("QtSlot()"))
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 :

a.emit(QtCore.SIGNAL("clicked()"))
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:

void valueChanged(int i);
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 :

void clicked(bool checked ! false);

Qt implémente cela tel que ce qui suit:

void clicked();
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 :

QtCore.pyqtSignature("int")
def on_spinbox_valueChanged(self, i):
   # i sera un entier.
   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 :

QtCore.pyqtSignature("")
def on_button_clicked(self):
   pass

Les commentaires sont fermé pour cet élément.