Créer les widgets

Exclusif Premium

Débloquez votre potentiel ! ✨

Cette session fait partie de notre programme Premium exclusif

+100h de formations exclusives
+180 exercices de code avancés
+100h de mentorats en réécriture
20 projets guidés pas à pas
Mentorats groupés hebdomadaires
Support individuel avec nos mentors

Prêt à passer au niveau supérieur ?

Découvrez tous les avantages Premium et transformez votre apprentissage dès aujourd'hui!

Inscris-toi

(c'est gratuit !)

Un compte est nécessaire pour participer aux discussions.

Créer un compte

Toutes les questions

Fethi CHOUDER

2 juin 2025

Résolue
2 réponses

Variables dynamiques vs dictionnaire pour la création de boutons

J'aurais une petite question. Lors de la création de la boucle pour générer les boutons, il est dit qu'un dictionnaire doit être créé pour que tous les boutons soient affectés à une clé et ne soient pas écrasés. Aurait-on cependant pu créer des variables dynamiques directement dans la boucle avec la fonction globals(), et nous épargner ainsi la création d'un dictionnaire, comme indiqué ci-dessous ? ![](/media/mentoring/question/37746/image-498x134.webp) Dans le cas où cela serait possible, quelle est cependant la meilleure solution ?

Patlord

24 mai 2024

Résolue
1 réponse

Impossible de créer une seconde instance QApplication

Quand je lance le script la première fois pour vérifier si la fenêtre d'application s'affiche correctement, pas de soucis. Par contre, dès que je relance le script, je reçois le message d'erreur: "Please destroy the QApplication singleton before creating a new QApplication instance." J'ai essayé de rajouter la condition : ``` if QApplication.instance(): app.quit() ``` mais là, il me dit que "app" n'est pas défini. J'ai remplacé cette ligne par "QApplication.instance().exit()" mais je reçois toujours le message d'erreur indiquant qu'une instance est toujours en cours. Auriez-vous une idée?

Créer les widgets

Pour créer les boutons, nous allons utiliser un dictionnaire qui contiendra le texte à afficher sur chaque bouton ainsi que les coordonnées du bouton en X et Y ainsi que la taille qu'ils doivent occuper sur la grille de notre layout :

BUTTONS = {"C": (1, 0, 1, 1),
           "/": (1, 3, 1, 1),
           "7": (2, 0, 1, 1),
           "8": (2, 1, 1, 1),
           "9": (2, 2, 1, 1),
           "x": (2, 3, 1, 1),
           "4": (3, 0, 1, 1),
           "5": (3, 1, 1, 1),
           "6": (3, 2, 1, 1),
           "-": (3, 3, 1, 1),
           "1": (4, 0, 1, 1),
           "2": (4, 1, 1, 1),
           "3": (4, 2, 1, 1),
           "+": (4, 3, 1, 1),
           "0": (5, 0, 1, 2),
           ".": (5, 2, 1, 1),
           "=": (5, 3, 1, 1)}

On crée ensuite un QGridLayout qui va nous permettre d'ajouter les widgets selon un agencement en grille :

from PySide6.QtWidgets import QApplication, QWidget, QGridLayout

BUTTONS = {"C": (1, 0, 1, 1),
           "/": (1, 3, 1, 1),
           "7": (2, 0, 1, 1),
           "8": (2, 1, 1, 1),
           "9": (2, 2, 1, 1),
           "x": (2, 3, 1, 1),
           "4": (3, 0, 1, 1),
           "5": (3, 1, 1, 1),
           "6": (3, 2, 1, 1),
           "-": (3, 3, 1, 1),
           "1": (4, 0, 1, 1),
           "2": (4, 1, 1, 1),
           "3": (4, 2, 1, 1),
           "+": (4, 3, 1, 1),
           "0": (5, 0, 1, 2),
           ".": (5, 2, 1, 1),
           "=": (5, 3, 1, 1)}


class Calculator(QWidget):
    def __init__(self):
        super().__init__()

        self.setWindowTitle("Calculatrice")

        self.main_layout = QGridLayout(self)

app = QApplication()
win = Calculator()
win.show()
app.exec()

!!!warning
Il ne faut pas oublier de parenter le layout à la fenêtre en passant self en argument lors de la création du QGridLayout.
!!!

On crée ensuite le QLineEdit qui servira à afficher le résultat de l'opération en affichant par défaut le nombre 0. Notes les guillemets autour du 0 : le QLineEdit n'accepte en effet que des chaînes de caractères.

from PySide6.QtWidgets import QApplication, QWidget, QGridLayout, QLineEdit, QPushButton

BUTTONS = {"C": (1, 0, 1, 1),
           "/": (1, 3, 1, 1),
           "7": (2, 0, 1, 1),
           "8": (2, 1, 1, 1),
           "9": (2, 2, 1, 1),
           "x": (2, 3, 1, 1),
           "4": (3, 0, 1, 1),
           "5": (3, 1, 1, 1),
           "6": (3, 2, 1, 1),
           "-": (3, 3, 1, 1),
           "1": (4, 0, 1, 1),
           "2": (4, 1, 1, 1),
           "3": (4, 2, 1, 1),
           "+": (4, 3, 1, 1),
           "0": (5, 0, 1, 2),
           ".": (5, 2, 1, 1),
           "=": (5, 3, 1, 1)}


class Calculator(QWidget):
    def __init__(self):
        super().__init__()

        self.setWindowTitle("Calculatrice")

        self.main_layout = QGridLayout(self)

        self.le_result = QLineEdit("0")
        self.main_layout.addWidget(self.le_result, 0, 0, 1, 4)

app = QApplication()
win = Calculator()
win.show()
app.exec()

Pour ajouter le QLineEdit au layout, on utilise la méthode addWidget.

Le premier argument correspond au widget que l'on souhaite ajouter au layout. On indique ensuite les coordonnées X et Y (ici 0, 0 car on souhaite placer le QLineEdit en partant en haut à gauche de la fenêtre).

Les 2 derniers arguments correspondent à la taille que doit occuper le widget en hauteur et en largeur. On indique donc 1 en hauteur et 4 en largeur :

self.main_layout.addWidget(self.le_result, 0, 0, 1, 4)

Il ne reste plus qu'à ajouter les boutons. On boucle sur les éléments de notre dictionnaire BUTTONS pour récupérer le texte et la position ainsi que la taille des boutons :

from PySide6.QtWidgets import QApplication, QWidget, QGridLayout, QLineEdit, QPushButton

BUTTONS = {"C": (1, 0, 1, 1),
           "/": (1, 3, 1, 1),
           "7": (2, 0, 1, 1),
           "8": (2, 1, 1, 1),
           "9": (2, 2, 1, 1),
           "x": (2, 3, 1, 1),
           "4": (3, 0, 1, 1),
           "5": (3, 1, 1, 1),
           "6": (3, 2, 1, 1),
           "-": (3, 3, 1, 1),
           "1": (4, 0, 1, 1),
           "2": (4, 1, 1, 1),
           "3": (4, 2, 1, 1),
           "+": (4, 3, 1, 1),
           "0": (5, 0, 1, 2),
           ".": (5, 2, 1, 1),
           "=": (5, 3, 1, 1)}


class Calculator(QWidget):
    def __init__(self):
        super().__init__()

        self.setWindowTitle("Calculatrice")

        self.buttons = {}

        self.main_layout = QGridLayout(self)

        self.le_result = QLineEdit("0")
        self.main_layout.addWidget(self.le_result, 0, 0, 1, 4)

        for button_text, button_position in BUTTONS.items():
            button = QPushButton(button_text)
            self.main_layout.addWidget(button, *button_position)
            self.buttons[button_text] = button


app = QApplication()
win = Calculator()
win.show()
app.exec()

Pour envoyer la position et la taille des boutons à la méthode addWidget, notez l'utilisation de l'unpacking (avec l'astérisque) :
self.main_layout.addWidget(button, *button_position)

Cela nous permet d'envoyer les 4 informations contenues dans le tuple (la position X,Y et la taille) de façon individuelles. Cela revient au même que de faire :
self.main_layout.addWidget(button, button_position[0], button_position[1], button_position[2], button_position[3])

Pour garder une trace des boutons et pouvoir les modifier par la suite, on passe par un autre dictionnaire, self.buttons. À chaque création d'un nouveau QPushButton, on ajoute une clé dans le dictionnaire avec le texte du bouton et le widget associé en valeur :

self.buttons[button_text] = button

Cela nous permettra par la suite d'accéder par exemple au bouton avec le nombre 1 de cette façon :
self.buttons["1"]

Ce n'est pas fini...

Tu as complété % du parcours 🔥

Termine l'intégralité de la formation pour pouvoir débloquer ton attestation de réussite.

Rechercher sur le site

Inscris-toi à Docstring

Pour commencer ton apprentissage.

Tu as déjà un compte ? Connecte-toi.