• Aucun résultat trouvé

l'interaction utilisateur. On va apprendre le modèle de connexion de signaux aux slots de Qt pour traiter les entrées et d'autres événements, ainsi que les dispositions (layouts) pour répartir de manière plus harmonieuse les widgets sur

Dans le document Le Mag Developpez (Page 35-38)

Je travaille également sur l'utilisation des lambdas dans les connexions signaux/slots, mais ce sera pour Qt5.

8. Les chaînes de caractères Unicode

Nous n'avons pas encore ajouté le support des nouveaux types de chaînes. Mais cela pourrait venir plus tard.

9. Allez-y et testez-le !

Si vous utilisez MSVC 2010 (Lien 157), il n'y a rien à faire, vous pouvez déjà utiliser certaines fonctionnalités telles que les lambdas ou les références rvalue. Si vous utilisez gcc (Lien 158), vous devez passer l'option -std=c++0x. Vous pouvez faire cela dans votre fichier projet qmake comme ceci :

QMAKE_CXXFLAGS += -std=c++0x

Si vous voulez compiler Qt en utilisant C++0x, vous pouvez faire :

CXXFLAGS="-std=c++0x" ./configure

Qt compilé avec le C++0x respecte la compatibilité binaire avec le bon vieux C++. Et vous n'avez pas besoin de compiler Qt avec C++0x pour écrire votre propre application en utilisant C++0x.

Retrouvez l'article d'Olivier Goffart traduit par Guillaume Belz en ligne : Lien 159

PyQt : signaux, slots et dispositions

1. La hiérarchie des classes de PyQt

PyQt se base complètement sur les concepts orientés objet, il est donc important de comprendre comme les classes sont liées les unes aux autres.

Presque toutes les classes GUI dérivent de leur classe abstraite, qui définit un comportement commun pour des widgets similaires. Ces classes abstraites (ou toute classe de widget) hérite de QWidget, la classe de base de tous les composants GUI affichables à l'écran. QWidget hérite elle-même de QObject, une classe qui n'a rien à voir avec les GUI, mais forme la classe de base de la majorité des classes de PyQt et aide à fournir certaines fonctionnalités du framework.

Le diagramme de hiérarchie suivant montre cela très clairement pour la classe QPushButton :

La classe QPaintDevice aide à dessiner des choses à l'écran, elle est donc utilisée pour tout ce qui y est

affichable.

Référence : Qwidget (Lien 160).

2. Signaux et slots

Toutes les interactions entre un utilisateur et un widget peuvent s'effectuer avec le concept de signaux et de slots.

Quand un utilisateur effectue une action sur un widget (un clic, un appui de touche ou le pointeur qui survole), un événement est généré. Ces événements de base peuvent être gérés avec le concept de signaux et de slots.

Très simplement, un signal est quelque chose qui est généré à chaque fois qu'un événement a lieu. Le signal est émis en interne par les classes de PyQt ou les vôtres. Pour gérer ces signaux, on utilise des slots. On donne à chaque signal un slot auquel il est connecté. Une fois connecté à un slot, à chaque fois qu'il est émis, le signal est capturé par le slot et exécute une fonction prédéfinie pour gérer l'événement.

En d'autres mots, un signal est quelque chose qui est émis à chaque événement, un slot est quelque chose qui reçoit ce signal avec ses arguments et exécute une routine.

Pour exemplifier ce concept, on va utiliser un QPushButton avec un QWidget pour la fenêtre. Le code suivant lance une application avec un bouton qui, lorsqu'il est cliqué, ferme l'application. On le fait en connectant le signal connected() du bouton au slot quit() de l'application.

PyQt : signaux, slots et dispositions

Après avoir vu ce à quoi une application PyQt simple ressemble au niveau du code, regardons de plus près

l'interaction utilisateur. On va apprendre le modèle de connexion de signaux aux slots de Qt pour traiter les entrées et

d'autres événements, ainsi que les dispositions (layouts) pour répartir de manière plus harmonieuse les widgets sur

une fenêtre.

# Programme 02 - signaux from PyQt4 import QtGui, QtCore import sys

if __name__=='__main__':

app = QtGui.QApplication(sys.argv) window = QtGui.QWidget()

# On crée la fenêtre principale avec un QWidget.

window.setWindowTitle("Signaux") # On en définit le titre : "Signaux".

button = QtGui.QPushButton("Appuyez", window) # On crée un bouton enfant, avec "Appuyez"

comme

# texte, dans la fenêtre parente. En spécifiant un

# objet parent, ce nouveau widget y est automatiquement

# ajouté.

button.resize(200, 40)

# On redimensionne le bouton : (200, 40) button.connect(button,

QtCore.SIGNAL("clicked()"),\

app, QtCore.SLOT("quit()"))

# On connecte le signal clicked du bouton au slot quit()

# de QApplication window.show()

# On affiche la fenêtre.

app.exec_()

3. Connecter un signal à un slot

La connexion est effectuée pour que certains événements particuliers appellent leur slot respectif. Toutes les classes dérivant de QObject supportent ces connexions. La syntaxe de connect() est simple :

object.connect(Signal_Widget, Signal, Slot_Widget, Slot)

La fonction connect() effectue une connexion entre deux ensembles de paramètres :

1. le signal :

• il est constitué par l'objet qui émet le signal et le type de signal que l'on veut gérer (SIGNAL(QString)),

• chaque widget émet un signal lors d'un événement, comme une interaction utilisateur ou une minuterie,

• ces signaux ne doivent pas être confondus avec des signaux POSIX ou UNIX, c'est un concept très différent au niveau du système d'exploitation ; 2. le slot :

• l'objet receveur et le slot qu'il doit exécuter dès la réception du signal (SLOT(QString)),

• chaque signal émis peut être géré par une fonction, un slot,

• un slot est exécuté à chaque fois qu'un

signal qui lui est connecté est émis par la classe émettrice.

QtCore.QObject est la classe qui fournit cette fonction de connexion. Puisque la classe en dérive, on peut l'utiliser depuis son instance. On peut donc remplacer la vingtième ligne par :

QtCore.QObject.connect(button, QtCore.SIGNAL("clicked()"),\

app, QtCore.SLOT("quit()"))

Un widget PyQt dispose de nombreux signaux et slots. Par exemple, un QAbstractButton possède les signaux clicked(), pressed(), released() et toggled(), ainsi que les slots click(), setChecked(Bool) et toggle(). PyQt fournit la majorité des fonctionnalités GUI que l'on peut imaginer.

Références : Qobject (Lien 161), signaux et slots (Lien 162) , QpushButton (Lien 163) et Qapplication (Lien 164) .

4. Dispositions (layouts)

En tentant de redimensionner l'exemple précédent, on a l'impression que le bouton est collé simplement dans la fenêtre. Il ne change pas de position, le contenu de la fenêtre ne change pas en fonction de l'écran de l'utilisateur.

Les dispositions peuvent aider à ce niveau - et pour bien d'autres choses aussi.

Comme le mot l'indique, les dispositions aident à disposer les widgets sur une fenêtre de manière propre. QLayout est la forme la plus basique de disposition et possède quatre sous-classes principales, de type Box, Grid, Form et Stacked.

Utiliser une disposition est simple avec PyQt. On doit juste attacher la disposition voulue à une fenêtre ou un widget et on y ajoute des composants, qui seront automatiquement disposés. Le prochain exemple les utilise.

Références : Qlayout (Lien 165), classes de disposition (Lien 166)

5. Passer des arguments aux slots

Les signaux et slots peuvent aussi transmettre des paramètres. Ceci est utile quand il y a une entrée ou quand des données doivent être envoyées automatiquement à chaque fois qu'un événement se produit.

Prenons un autre exemple, avec des paramètres. On va y connecter un éditeur sur une ligne à un label. Quand on entre du texte dans l'éditeur, des événements sont automatiquement générés et un slot du label va être exécuté pour changer le texte affiché pour celui qui vient

PyQt : signaux, slots et dispositions

Après avoir vu ce à quoi une application PyQt simple ressemble au niveau du code, regardons de plus près

l'interaction utilisateur. On va apprendre le modèle de connexion de signaux aux slots de Qt pour traiter les entrées et

d'autres événements, ainsi que les dispositions (layouts) pour répartir de manière plus harmonieuse les widgets sur

une fenêtre.

d'être tapé. Pour ceci, on utilise un QLabel pour le label et un QLineEdit pour l'éditeur.

Quelles sont les étapes à suivre pour obtenir le code ci-dessous ?

1. Importer les classes nécessaires.

2. Créer une instance de QApplication.

3. Créer une fenêtre (QWidget).

4. Y attacher un QHBoxLayout.

5. Créer un widget d'entrée et l'ajouter à la disposition.

6. Créer un widget d'affichage et l'ajouter à la disposition.

7. Connecter le signal textChanged(QString) de l'éditeur au slot setText(QString) du label.

8. Afficher la fenêtre.

9. Lancer la boucle principale.

# Programme 03 - signaux et slots avec arguments from PyQt4.QtCore import SIGNAL, SLOT

from PyQt4.QtGui import QApplication, QWidget,\

QLineEdit, QLabel, QHBoxLayout import sys

if __name__=='__main__':

App = QApplication(sys.argv) Window = QWidget()

Window.setWindowTitle("Arguments") Layout = QHBoxLayout(Window) Line = QLineEdit()

Layout.addWidget(Line) Label = QLabel() Layout.addWidget(Label) Line.connect(Line,

SIGNAL("textChanged(QString)"),\

Label, SLOT("setText(QString)")) Window.show()

App.exec_()

Quand l'utilisateur entre ou modifie le texte du widget d'édition, un signal textChanged(QString) est émis avec la nouvelle chaîne en paramètre. On l'intercepte et on y connecte le slot (et fonction) setText(QString) du label.

Ainsi, la chaîne modifiée voyage de l'éditeur au label et est affichée, le tout pour chaque changement, fût-ce un caractère.

La disposition possède une fonction intéressante, addWidget(), qui prend un widget et l'ajoute à la géométrie de la disposition. Cette méthode prend aussi un paramètre de facteur d'extension et un autre d'alignement. La disposition ajuste automatiquement les tailles des widgets, en se basant sur la taille de l'entrée dans cet exemple. Si on augmente la taille de la fenêtre, la disposition va s'adapter de même.

Si le concept de signaux et de slots semble encore confus, le graphique ci-dessous va l'éclairer un peu plus.

Références : QlineEdit (Lien 167), Qlabel (Lien 168), QHBoxLayout (Lien 169).

6. Exercice

Utilisez un QPushButton dans une fenêtre QWidget et changez son texte à chaque fois qu'il est cliqué. Aussi, ajoutez une disposition pour la fenêtre avec le bouton.

Chaque fois que le bouton est cliqué, son texte doit changer. Par exemple, si le texte du bouton est Hello!, après un clic il devient PyQt et un dernier le fait revenir à Hello!. Assurez-vous qu'il s'agrandit en même temps que la fenêtre.

7. Notes

On peut passer une fonction directement à connect() pour servir de slot. Elle ne doit pas forcément être un slot fourni par PyQt.

On peut aussi également écrire ses propres signaux et slots pour certains événements.

Tous les composants GUI n'ont pas une classe abstraite.

Elle n'existe qu'en cas de widget ou d'item qui peut être étendu de plus d'une manière.

Retrouvez l'article de Harsh traduit par Thibaut Cuvelier en ligne : Lien 170

Dans le document Le Mag Developpez (Page 35-38)