Afin de pouvoir personnaliser votre classeur sans détruire le classeur sur lequel travaille votre voisin, vous allez tout d'abord aller dans le menu File puis Make a copy.... Renommez le classeur en ajoutant votre nom à la fin du nom de fichier par exemple.

PySide 2 : Ligne de saisie et événement

Lien vers la doc

On commence bien sûr par rappeler le lien vers la doc PySide...

https://deptinfo-ensip.univ-poitiers.fr/ENS/pyside-docs/index.html

On importe les librairies Qt comme d'habitude

In [ ]:
from PySide.QtCore import *
from PySide.QtGui import *
import sys

Le but de l'activité

Nous souhaitons réaliser une application très simple comprenant un texte et un champ de saisie :

Capture

Lorsque un texte est saisi, nous voulons que le texte soit affiché dans le label.

Conception de l'interface

Contrairement à notre Hello World, notre interface se compose de deux Widgets. Nous allons donc créer une classe MainWindow héritant de QWidget.

Une recherche dans le Fantastic Manual nous montre que QWidget est la classe de base la plus simple pour les interfaces utilisateurs, comme on peut le voir sur l'arbre de hiérarchie :

QWidget

Un coup d'oeil aux fonctions vous montrera la richesse de ce composant de base ! pas de panique nous n'aurons pas besoin de tout cela !

In [ ]:
class MainWindow(QWidget):
    def __init__(self, parent=None):
        QWidget.__init__(self, parent)
        
        self.monLabel=QLabel("Mon texte")
        self.maLigne=QLineEdit()
        
        self.setWindowTitle("Classeur Pyside 2")
        
        layout=QVBoxLayout()
        layout.addWidget(self.monLabel)
        layout.addWidget(self.maLigne)
        self.setLayout(layout)

Examinons ce code :

  • la définition de la classe ressemble à l'activité précédente à ceci près qu'on hérite de QWidget au lieu de QLabel directement.
  • ensuite nous créons nos deux composants graphique :

    • un QLabel pour le texte à afficher. On remarquera que le texte peut être passé directement lors de la création sans passer par la méthode setText()*
    • un QLineEdit poiur le champ de saisie --> RTFM

      Remarque : les widgets sont des variables d'instance, c'est à dire que le nom de la variable est précédée de self. Ainsi, le widget est accessible depuis d'autres méthodes que la méthode init() depuis laquelle il a été créé. Nous verrons bientôt pourquoi cela est important !

  • on positionne le titre de la fenêtre
  • on dispose nos éléments dans la fenêtre grâce à un layout vertical

Nous allons expliquer la disposition plus en détail

Utilisation des layouts

Les layouts sont des mécanismes intégrés à Qt pour faciliter la disposition automatique des widgets sur la fenêtre. Nous en utiliserons principalement 3 :

  • QVBoxLayout() : pour une disposition verticale des widgets dans la fenêtre
  • QHBoxLayout() : pour une disposition horizontale des widgets dans la fenêtre
  • QGridLayout() : pour une disposition des widgets sur une grille

Pour utiliser un layout, il faut trois étapes :

  1. on crée un objet layout correspondant à notre disposition : layout=QVBoxLayout()
  2. on ajoute nos widgets au layout grâce à la méthode layout.addWidget()
  3. on associe le layout à notre fenêtre principale grâce à la commande `self.setLayout(layout)

Remarque : On peut ainsi faire des mise en page assez sophistiquées car on peut mettre des layouts dans des layouts ! nous en verrons des exemples plus tard.

On donne vie à notre application

In [ ]:
try:
    app = QApplication(sys.argv)
except RuntimeError:
    app=QApplication.instance()
form = MainWindow()
form.show()
app.exec_()

Connection des événements

et après ? cette application ne fait rien. On tape du texte dans le champ de saisie mais rien ne se passe. C'est normal, nous n'avons rien fait pour cela !

Nous voudrions que quand l'utilisateur appuie sur Entrée, le texte du champ de saisie soit recopié dans le label.

Pur cela, nous allons devoir connecter une méthode Python que nous devons écrire à l'événement "La touche Entrée a été pressée".

Un événement en Qt est un signal. Recherchez dans le Fantastic Manual le nom du signal correspondant à l'événement que nous recherchons.

Le nom du signal est returnPressed ()

Complétons à présent notre classe MainWindow

In [ ]:
class MainWindow(QWidget):
    def __init__(self, parent=None):
        QWidget.__init__(self, parent)
        
        self.monLabel=QLabel("Mon texte")
        self.maLigne=QLineEdit()
        
        self.setWindowTitle("Classeur Pyside 2")
        
        layout=QVBoxLayout()
        layout.addWidget(self.monLabel)
        layout.addWidget(self.maLigne)
        self.setLayout(layout)
        
        # On connecte le signal returnPressed () à la méthode updateUi de notre classe
        self.maLigne.returnPressed.connect(self.updateUi)

    def updateUi(self):
        self.monLabel.setText(self.maLigne.text())
        # Heuresement qu'on a utilisé des variables d'instance
        # sinon, monLabel et maLigne seraient locales à la méthode __init__() donc invisibles ici

Pour relancer notre application, on peut se contenter des 3 lignes suivantes puisque la variable app vit encore dans notre kernel iPython :)

In [ ]:
form = MainWindow()
form.show()
app.exec_()

A vous de jouer

A présent, vous voudrions que lorsque la touche Entrée est pressée, le champ de saisie soit effacé !

Recherchez dans le Fantastic Manual le nom de la méthode à utiliser pour cela.

In [ ]:
# copiez/collez et modifiez la classe MainWindow ici
In [ ]:
# Pour relancer votre appli :
form = MainWindow()
form.show()
app.exec_()

One more thing...

Pour rendre votre application encore plus attrayante :), vous pouvez indiquer un texte dans le champ d'édition qui sera grisé et qui invitera l'utilisateur à entrer du texte. Ce texte disparaît une fois que la saisie commence. Ce texte est stocké dans la propriété placeholderText de QLineEdit.

Modifiez votre programme de manière à indiquer "Entrez votre texte ici" dans le champ de saisie lorsque celui-ci est vide et inactif.

Développer votre application

Votre mission, si vous l'acceptez, est de développer l'application suivante : Calculatrice

Indice : La zone où sont affichées les réponses est un widget de type QTextBrowser.

RTFM :)

In [ ]:
# Vottre application ici !