Créer un menu simple avec Matplotlib

PythonPythonBeginner
Pratiquer maintenant

This tutorial is from open-source community. Access the source code

💡 Ce tutoriel est traduit par l'IA à partir de la version anglaise. Pour voir la version originale, vous pouvez cliquer ici

Introduction

Dans ce laboratoire, vous allez apprendre à créer un menu simple à l'aide de Matplotlib. Le menu contiendra une liste d'éléments, chacun d'entre eux pouvant être sélectionné par l'utilisateur. L'élément sélectionné déclenchera ensuite une fonction de rappel qui effectuera une certaine action.

Conseils sur la machine virtuelle

Une fois le démarrage de la machine virtuelle terminé, cliquez dans le coin supérieur gauche pour basculer vers l'onglet Notebook pour accéder à Jupyter Notebook pour la pratique.

Parfois, vous devrez peut-être attendre quelques secondes pour que Jupyter Notebook ait fini de charger. La validation des opérations ne peut pas être automatisée en raison des limitations de Jupyter Notebook.

Si vous rencontrez des problèmes pendant l'apprentissage, n'hésitez pas à demander à Labby. Donnez votre feedback après la session, et nous réglerons rapidement le problème pour vous.

Importation des bibliothèques

Pour commencer, nous devons importer les bibliothèques nécessaires. Dans ce cas, nous devons importer matplotlib.pyplot, matplotlib.artist, matplotlib.patches et IdentityTransform à partir de matplotlib.transforms.

import matplotlib.pyplot as plt
import matplotlib.artist as artist
import matplotlib.patches as patches
from matplotlib.transforms import IdentityTransform

Définition de la classe ItemProperties

Ensuite, nous définissons une classe ItemProperties qui sera utilisée pour définir les propriétés de chaque élément du menu. Nous pouvons définir la taille de police, la couleur de l'étiquette, la couleur d'arrière-plan et la valeur alpha pour chaque élément à l'aide de cette classe.

class ItemProperties:
    def __init__(self, fontsize=14, labelcolor='black', bgcolor='yellow',
                 alpha=1.0):
        self.fontsize = fontsize
        self.labelcolor = labelcolor
        self.bgcolor = bgcolor
        self.alpha = alpha

Maintenant, nous définissons une classe MenuItem qui sera utilisée pour créer chaque élément du menu. Nous passons la figure, la chaîne de caractères d'étiquette, les propriétés, les propriétés au survol et la fonction de rappel lors de la sélection en tant que paramètres à cette classe. La classe MenuItem hérite de la classe artist.Artist.

class MenuItem(artist.Artist):
    padx = 5
    pady = 5

    def __init__(self, fig, labelstr, props=None, hoverprops=None,
                 on_select=None):
        super().__init__()

        self.set_figure(fig)
        self.labelstr = labelstr

        self.props = props if props is not None else ItemProperties()
        self.hoverprops = (
            hoverprops if hoverprops is not None else ItemProperties())
        if self.props.fontsize!= self.hoverprops.fontsize:
            raise NotImplementedError(
               'support for different font sizes not implemented')

        self.on_select = on_select

        ## Setting the transform to IdentityTransform() lets us specify
        ## coordinates directly in pixels.
        self.label = fig.text(0, 0, labelstr, transform=IdentityTransform(),
                              size=props.fontsize)
        self.text_bbox = self.label.get_window_extent(
            fig.canvas.get_renderer())

        self.rect = patches.Rectangle((0, 0), 1, 1)  ## Will be updated later.

        self.set_hover_props(False)

        fig.canvas.mpl_connect('button_release_event', self.check_select)

    def check_select(self, event):
        over, _ = self.rect.contains(event)
        if not over:
            return
        if self.on_select is not None:
            self.on_select(self)

    def set_extent(self, x, y, w, h, depth):
        self.rect.set(x=x, y=y, width=w, height=h)
        self.label.set(position=(x + self.padx, y + depth + self.pady/2))
        self.hover = False

    def draw(self, renderer):
        self.rect.draw(renderer)
        self.label.draw(renderer)

    def set_hover_props(self, b):
        props = self.hoverprops if b else self.props
        self.label.set(color=props.labelcolor)
        self.rect.set(facecolor=props.bgcolor, alpha=props.alpha)

    def set_hover(self, event):
        """
        Update the hover status of event and return whether it was changed.
        """
        b, _ = self.rect.contains(event)
        changed = (b!= self.hover)
        if changed:
            self.set_hover_props(b)
        self.hover = b
        return changed

Nous devons également définir une classe Menu qui sera utilisée pour créer le menu. Nous passons la figure et la liste d'éléments du menu en tant que paramètres à cette classe.

class Menu:
    def __init__(self, fig, menuitems):
        self.figure = fig

        self.menuitems = menuitems

        maxw = max(item.text_bbox.width for item in menuitems)
        maxh = max(item.text_bbox.height for item in menuitems)
        depth = max(-item.text_bbox.y0 for item in menuitems)

        x0 = 100
        y0 = 400

        width = maxw + 2*MenuItem.padx
        height = maxh + MenuItem.pady

        for item in menuitems:
            left = x0
            bottom = y0 - maxh - MenuItem.pady

            item.set_extent(left, bottom, width, height, depth)

            fig.artists.append(item)
            y0 -= maxh + MenuItem.pady

        fig.canvas.mpl_connect('motion_notify_event', self.on_move)

    def on_move(self, event):
        if any(item.set_hover(event) for item in self.menuitems):
            self.figure.canvas.draw()

Maintenant, nous pouvons créer le menu. Nous créons une nouvelle figure et ajustons la marge gauche. Ensuite, nous créons une liste d'éléments du menu et les ajoutons au menu. Nous définissons également une fonction de rappel pour chaque élément qui affichera l'élément sélectionné.

fig = plt.figure()
fig.subplots_adjust(left=0.3)
props = ItemProperties(labelcolor='black', bgcolor='yellow',
                       fontsize=15, alpha=0.2)
hoverprops = ItemProperties(labelcolor='white', bgcolor='blue',
                            fontsize=15, alpha=0.2)

menuitems = []
for label in ('open', 'close','save','save as', 'quit'):
    def on_select(item):
        print('you selected %s' % item.labelstr)
    item = MenuItem(fig, label, props=props, hoverprops=hoverprops,
                    on_select=on_select)
    menuitems.append(item)

menu = Menu(fig, menuitems)
plt.show()

Sommaire

Félicitations ! Vous avez réussi à créer un menu simple à l'aide de Matplotlib. Vous avez appris à créer une classe MenuItem, une classe Menu et à définir les propriétés de chaque élément. Vous avez également appris à créer une fonction de rappel pour chaque élément qui effectuera une certaine action.