import tkinter
from random import randint

def randomRGBString():
    """
    :return: une chaîne de caractères représentant une couleur RGB aléatoire
    """
    return "#" + ("%06x" % randint(0, 16777215))


def petitRectangle(cv: tkinter.Canvas, nom: str = None):
    """
    Dessine un petit rectangle de taille 30x30 dans un `Canvas` de couleur aléatoire et portant
    potentiellement un `tag`.
    :param cv: le `Canvas` dans lequel dessiner le rectangle
    :param nom: le tag éventuel à associer au rectangle
    :return: un objet de type Tkinter.Rectangle positionné aléatoirement dans `cv`
    """
    x = 30 + randint(0, 270)
    y = 30 + randint(0, 270)
    return cv.create_rectangle(x, y, x + 30, y + 30, fill=randomRGBString(), tags=nom)


def changerCouleur(canvas, objet):
    """
    Change de façon aléatoire la couleur d'un objet dans un canvas
    :param canvas: le `Canvas` auquel appartient l'objet
    :param objet: l'objet à modifier
    :return: None
    """
    canvas.itemconfig(objet, fill=randomRGBString())


if __name__ == '__main__':
    # Création de la fenêtre principale
    root = tkinter.Tk()
    # Addition d'un titre de fenêtre
    root.title("Mon application")

    # Ajout d'un widget dans la fenêtre principale
    myCanvas = tkinter.Canvas(root, bg="white", height=300, width=300)
    myCanvas.pack()

    # Ajout d'un widget `Label` dans la fenêtre principale
    lbl = tkinter.Label(root, text="Rien")
    # Ajout d'un widget `Button` dans la fenêtre principale
    btn = tkinter.Button(root, text="Bouton à cliquer")

    lbl.pack()
    btn.pack()

    # Dessin de 2 rectangles aléatoires dans le `Canvas` (dont `rectangle2` avec le tag "rect")
    rectangle1 = petitRectangle(myCanvas)
    rectangle2 = petitRectangle(myCanvas, "rect")

    def handler(e=None):
        """
        Gestionnaire d'événement qui change aléatoirement la couleur de l'objet `rectangle1`
        et qui change le texte du label `lbl` en "Coucou"
        :param e: l'événement à l'origine de l'exécution
        :return: None
        """
        if e:
            print(e.widget)
            print(e.x)
        changerCouleur(myCanvas, rectangle1)
        lbl.config(text="Coucou")
        # Noter que les événements peuvent être ajoutés à la main à la boucle d'événements
        # Ici, on crée une boucle infinie d'événements se répétant toutes les 1000 millisecondes.
        # myCanvas.after(1000, handlerBouton,e)

    # Association du gestionnaire d'événement au bouton `btn`
    # On observe qu'à chaque clic sur le bouton, le `rectangle1 change de couleur
    btn.config(command=handler)

    # Association du gestionnaire d'événement au clic de bouton gauche à tous les objets
    # du Canvas portant le label "rect" (en occurrence `rectangle2`
    # Observer que des clics sur `rectangle2` changent la couleur de `rectangle1`
    # (tout comme les clics sur le bouton `btn`)
    myCanvas.tag_bind("rect", "<Button-1>", handler)

    # Association du gestionnaire d'événement à une frappe clavier quelconque n'importe où dans
    # la fenêtre principale `root`
    # Observer que des frappes clavier changent la couleur de `rectangle1`
    # (tout comme les autre actions précédentes)
    root.bind("<Key>", handler)

    # Démarrage effectif de l'application (boucle de gestion des événements)
    root.mainloop()
