trouver un expert Python
- Premiers pas avec la bibliothèque NLTK de Python – Real Python
- Tinkerwell pour WordPress • WPShout
- Épisode # 308 Docker pour les développeurs Python (édition 2021)
- Un examen honnête des 6 sociétés d'hébergement WordPress les mieux gérées
- Épisode n ° 174 Entrer en Python à partir d'une autre industrie (partie 2)
Il existe de nombreux kits d'outils d'interface utilisateur graphique (GUI) que vous pouvez utiliser avec le langage de programmation Python. Les trois grands sont Tkinter, wxPython et PyQt. Chacune de ces boîtes à outils fonctionnera sous Windows, macOS et Linux, PyQt ayant la capacité supplémentaire de fonctionner sur mobile.
Une interface utilisateur graphique est une application dotée de boutons, de fenêtres et de nombreux autres widgets que l'utilisateur peut utiliser pour interagir avec votre application. Un bon exemple serait un navigateur Web. Il comporte des boutons, des onglets et une fenêtre principale dans laquelle tout le contenu est chargé.
Dans cet article, vous apprendrez à créer une interface utilisateur graphique avec Python à l'aide de la boîte à outils de l'interface graphique wxPython.
Voici les sujets abordés:
- Débuter avec wxPython
- Définition d'une interface graphique
- Création d'une application squelette
- Création d'une application opérationnelle
Commençons à apprendre!
Débuter avec wxPython
La boîte à outils de l'interface graphique wxPython est un wrapper Python autour d'une bibliothèque C ++ appelée wxWidgets. La première version de wxPython date de 1998. WxPython existe depuis assez longtemps. La principale différence de wxPython par rapport à d’autres outils, tels que PyQt ou Tkinter, est-ce que wxPython utilise les widgets réels sur la plate-forme native autant que possible. Cela donne aux applications wxPython une apparence native pour le système d'exploitation sur lequel elles s'exécutent.
PyQt et Tkinter dessinent tous deux leurs widgets eux-mêmes. C’est pourquoi ils ne correspondent pas toujours aux widgets natifs, bien que PyQt soit très proche.
Cela ne veut pas dire que wxPython ne supporte pas les widgets personnalisés. En fait, la boîte à outils wxPython contient de nombreux widgets personnalisés, ainsi que des dizaines sur des dizaines de widgets principaux. La page de téléchargements wxPython comporte une section intitulée Fichiers supplémentaires cela vaut la peine de vérifier.
Ici, il y a un téléchargement du paquet de démonstration wxPython. Ceci est une jolie petite application qui montre la grande majorité des widgets inclus dans wxPython. La démo permet à un développeur de visualiser le code dans un onglet et de l'exécuter dans un deuxième onglet. Vous pouvez même modifier et ré-exécuter le code dans la démo pour voir comment vos modifications affectent l'application.
Installer wxPython
Vous utiliserez la dernière version de wxPython pour cet article, à savoir wxPython 4, également connu sous le nom de Phoenix. Les versions wxPython 3 et wxPython 2 sont construites uniquement pour Python 2. Lorsque Robin Dunn, le principal responsable de la maintenance de wxPython, a créé la version wxPython 4, il a déconseillé de nombreux alias et nettoyé beaucoup de code pour rendre wxPython plus pythonique et plus facile à gérer.
Vous voudrez peut-être consulter les liens suivants si vous migrez d’une ancienne version de wxPython vers wxPython 4 (Phoenix):
Le paquet wxPython 4 est compatible avec Python 2.7 et Python 3.
Vous pouvez maintenant utiliser pépin
pour installer wxPython 4, ce qui n’était pas possible dans les anciennes versions de wxPython. Vous pouvez procéder comme suit pour l’installer sur votre ordinateur:
Remarque: Sur Mac OS X, vous aurez besoin d’un compilateur installé, tel que XCode pour que l'installation se termine avec succès. Linux peut également nécessiter l’installation de certaines dépendances avant le pépin
l'installateur fonctionnera correctement.
Par exemple, je devais installer freeglut3-dev, libgstreamer-plugins-base0.10-dev, et libwebkitgtk-3.0-dev sur Xubuntu pour le faire installer.
Heureusement, les messages d'erreur qui pépin
les affichages sont utiles pour déterminer ce qui manque, et vous pouvez utiliser la section des conditions préalables de la page wxPython Github pour vous aider à trouver les informations dont vous avez besoin si vous souhaitez installer wxPython sur Linux.
Il existe des molettes Python disponibles pour les versions les plus courantes de Linux que vous pouvez trouver dans la section Extras Linux avec les versions GTK2 et GTK3. Pour installer l'une de ces roues, utilisez la commande suivante:
$ pip install -U -f https://extras.wxpython.org/wxPython4/extras/linux/gtk3/ubuntu-18.04/ wxPython
Assurez-vous que vous avez modifié la commande ci-dessus pour qu'elle corresponde à votre version de Linux.
Définition d'une interface graphique
Comme cela a été mentionné dans l'introduction, une interface utilisateur graphique (GUI) est une interface qui est dessinée à l'écran pour permettre à l'utilisateur d'interagir.
Les interfaces utilisateur ont des composants communs:
- Fenêtre principale
- Menu
- Barre d'outils
- Boutons
- Entrée de texte
- Étiquettes
Tous ces articles sont connus sous le nom générique widgets. Il existe de nombreux autres widgets courants et de nombreux widgets personnalisés pris en charge par wxPython. Un développeur prend les widgets et les organise de manière logique sur une fenêtre avec laquelle l'utilisateur peut interagir.
Boucles d'événement
Une interface utilisateur graphique fonctionne en attendant que l'utilisateur fasse quelque chose. Le quelque chose s'appelle un un événement. Les événements se produisent lorsque l'utilisateur tape quelque chose alors que votre application est active ou lorsqu'il utilise sa souris pour appuyer sur un bouton ou un autre widget.
Sous les couvertures, la boîte à outils GUI exécute une boucle infinie appelée un boucle d'événement. La boucle d'événements n'attend que les événements, puis agit en fonction de ce que le développeur a codé pour l'application. Lorsque l'application n'intercepte pas un événement, elle ignore en fait qu'il s'est même produit.
Lorsque vous programmez une interface utilisateur graphique, gardez à l’esprit que vous devrez connecter chacun des widgets à gestionnaires d'événements afin que votre application fasse quelque chose.
Lorsque vous travaillez avec des boucles d'événement, vous devez prendre en compte une considération particulière: elles peuvent être bloquées. Lorsque vous bloquez une boucle d'événement, l'interface graphique devient insensible et semble geler pour l'utilisateur.
Tout processus que vous lancez dans une interface utilisateur graphique qui prend plus d'un quart de seconde devrait probablement être lancé en tant que thread ou processus distinct. Cela empêchera votre interface graphique de geler et donnera à l'utilisateur une meilleure expérience utilisateur.
Le framework wxPython dispose de méthodes spéciales thread-safe que vous pouvez utiliser pour communiquer avec votre application afin de lui indiquer que le thread est terminé ou de le mettre à jour.
Créons une application squelette pour montrer le fonctionnement des événements.
Création d'une application squelette
Un squelette d’application dans un contexte d’interface graphique est une interface utilisateur avec des widgets n’ayant aucun gestionnaire d’événements. Celles-ci sont utiles pour le prototypage. En gros, vous créez simplement l'interface graphique et la présentez à vos parties prenantes pour approbation avant de passer beaucoup de temps sur la logique d'arrière-plan.
Commençons par créer un Bonjour le monde
application avec wxPython:
importation wx
app = wx.App()
Cadre = wx.Cadre(parent=Aucun, Titre='Bonjour le monde')
Cadre.Spectacle()
app.Boucle principale()
Remarque: Les utilisateurs Mac peuvent recevoir le message suivant: Ce programme a besoin d'accéder à l'écran. S'il vous plaît, utilisez une version Framework de python, et uniquement lorsque vous êtes connecté à l'écran principal de votre Mac. Si vous voyez ce message et que vous n'exécutez pas virtualenv, vous devez exécuter votre application avec python au lieu de python. Si vous exécutez wxPython à partir d'un virtualenv, consultez le wiki wxPython pour la solution.
Dans cet exemple, vous avez deux parties: wx.App
et le wx.Frame
. le wx.App
est l’application wxPython et est nécessaire pour exécuter votre interface graphique. le wx.App
commence quelque chose appelé un .Boucle principale()
. C'est la boucle d'événement que vous avez apprise dans la section précédente.
L’autre pièce du puzzle est wx.Frame
, ce qui créera une fenêtre avec laquelle l’utilisateur pourra interagir. Dans ce cas, vous avez dit à wxPython que le cadre n’a pas de parent et que son titre est Bonjour le monde
. Voici à quoi ça ressemble quand vous exécutez le code:
Remarque: L'application sera différente lorsque vous l'exécutez sur Mac ou Windows.
Par défaut, un wx.Frame
comprendra des boutons Réduire, Agrandir et Quitter en haut. Normalement, vous ne créez pas d’application de cette manière. La plupart du code wxPython vous obligera à sous-classer le wx.Frame
et d'autres widgets afin que vous puissiez obtenir toute la puissance de la boîte à outils.
Prenons un moment pour réécrire votre code en tant que classe:
importation wx
classe MyFrame(wx.Cadre):
def __init__(soi):
super().__init__(parent=Aucun, Titre='Bonjour le monde')
soi.Spectacle()
si __prénom__ == '__principale__':
app = wx.App()
Cadre = MyFrame()
app.Boucle principale()
Vous pouvez utiliser ce code comme modèle pour votre application. Cependant, cette application n’a pas beaucoup d’effet, prenons donc quelques instants pour en apprendre un peu plus sur certains des autres widgets que vous pourriez ajouter.
Widgets
La boîte à outils wxPython propose plus de cent widgets. Cela vous permet de créer des applications riches, mais il peut également être difficile d’essayer de déterminer quel widget utiliser. C'est pourquoi le wxPython Demo est utile car il possède un filtre de recherche que vous pouvez utiliser pour vous aider à trouver les widgets pouvant s’appliquer à votre projet.
La plupart des applications graphiques permettent à l'utilisateur de saisir du texte et d'appuyer sur un bouton. Continuons et ajoutons ces widgets:
importation wx
classe MyFrame(wx.Cadre):
def __init__(soi):
super().__init__(parent=Aucun, Titre='Bonjour le monde')
panneau = wx.Panneau(soi)
soi.text_ctrl = wx.TextCtrl(panneau, pos=(5, 5))
mon_btn = wx.Bouton(panneau, étiquette='Press Me', pos=(5, 55))
soi.Spectacle()
si __prénom__ == '__principale__':
app = wx.App()
Cadre = MyFrame()
app.Boucle principale()
Lorsque vous exécutez ce code, votre application devrait ressembler à ceci:
Le premier widget que vous devez ajouter est quelque chose appelé wx.Panel
. Ce widget n'est pas obligatoire, mais recommandé. Sous Windows, vous devez utiliser un panneau afin que la couleur d'arrière-plan du cadre soit la bonne nuance de gris. La traversée des onglets est désactivée sans Panel sous Windows.
Lorsque vous ajoutez le widget de panneau à un cadre et que celui-ci est l'unique enfant du cadre, il se développe automatiquement pour remplir le cadre avec lui-même.
La prochaine étape consiste à ajouter un wx.TextCtrl
au panneau. Le premier argument pour presque tous les widgets est le parent sur lequel le widget doit aller. Dans ce cas, vous voulez que le contrôle de texte et le bouton soient au-dessus du panneau, c'est donc le parent que vous spécifiez.
Vous devez également indiquer à wxPython où placer le widget, ce que vous pouvez faire en passant une position via le pos
paramètre. Dans wxPython, l'emplacement d'origine est (0,0), qui est le coin supérieur gauche du parent. Ainsi, pour le contrôle de texte, vous indiquez à wxPython que vous souhaitez positionner son coin supérieur gauche à 5 pixels de la gauche (x) et à 5 pixels du haut (y).
Ensuite, vous ajoutez votre bouton au panneau et lui donnez une étiquette. Pour éviter le chevauchement des widgets, vous devez définir la coordonnée y sur 55 comme position du bouton.
Positionnement absolu
Lorsque vous fournissez des coordonnées exactes pour la position de votre widget, la technique que vous avez utilisée est appelée positionnement absolu. La plupart des kits d’outils graphiques offrent cette possibilité, mais ce n’est pas vraiment recommandé.
Au fur et à mesure que votre application devient plus complexe, il devient difficile de garder une trace de tous les emplacements des widgets et si vous devez déplacer les widgets. Réinitialiser toutes ces positions devient un cauchemar.
Heureusement, tous les kits d’outils d’interface graphique modernes offrent une solution, ce que vous apprendrez ensuite.
Calibreurs (Dimensionnement dynamique)
La boîte à outils wxPython comprend calibreurs, qui sont utilisés pour créer des mises en page dynamiques. Ils gèrent l'emplacement de vos widgets pour vous et les ajustent lorsque vous redimensionnez la fenêtre de l'application. D'autres boîtes à outils de l'interface graphique feront référence aux calibreurs en tant que dispositions, ce que fait PyQt.
Voici les principaux types de calibreurs que vous verrez le plus souvent utilisés:
wx.BoxSizer
wx.GridSizer
wx.FlexGridSizer
Ajoutons un wx.BoxSizer
à votre exemple et voir si nous pouvons le faire fonctionner un peu plus bien:
importation wx
classe MyFrame(wx.Cadre):
def __init__(soi):
super().__init__(parent=Aucun, Titre='Bonjour le monde')
panneau = wx.Panneau(soi)
mon_sizer = wx.BoxSizer(wx.VERTICALE)
soi.text_ctrl = wx.TextCtrl(panneau)
mon_sizer.Ajouter(soi.text_ctrl, 0, wx.TOUT | wx.DÉVELOPPER, 5)
mon_btn = wx.Bouton(panneau, étiquette='Press Me')
mon_sizer.Ajouter(mon_btn, 0, wx.TOUT | wx.CENTRE, 5)
panneau.SetSizer(mon_sizer)
soi.Spectacle()
si __prénom__ == '__principale__':
app = wx.App()
Cadre = MyFrame()
app.Boucle principale()
Ici, vous créez une instance de wx.BoxSizer
et le passer wx.VERTICAL
, l’orientation à laquelle les widgets sont ajoutés à la calculatrice.
Dans ce cas, les widgets seront ajoutés verticalement, ce qui signifie qu'ils seront ajoutés un à un, de haut en bas. Vous pouvez également définir l’orientation d’un BoxSizer sur wx.HORIZONTAL
. Lorsque vous faites cela, les widgets sont ajoutés de gauche à droite.
Pour ajouter un widget à un classeur, vous utiliserez .Ajouter()
. Il accepte jusqu'à cinq arguments:
la fenêtre
(le widget)proportion
drapeau
frontière
données d'utilisateur
le la fenêtre
l'argument est le widget à ajouter en proportion
définit combien d'espace par rapport aux autres widgets du sizer ce widget devrait prendre. Par défaut, c'est zéro, ce qui indique à wxPython de laisser le widget à sa proportion par défaut.
Le troisième argument est drapeau
. Vous pouvez en fait passer plusieurs drapeaux si vous le souhaitez tant que vous les séparez avec un caractère de pipe: |
. Le toolkit wxPython utilise |
d'ajouter des drapeaux en utilisant une série de blocs d'opérations au niveau des bits.
Dans cet exemple, vous ajoutez le contrôle de texte avec le wx.ALL
et wx.EXPAND
drapeaux. le wx.ALL
drapeau indique à wxPython que vous souhaitez ajouter une bordure sur tous les côtés du widget en wx.EXPAND
permet aux widgets de s’étendre autant que possible au sein de la dimensionnante.
Enfin, vous avez le frontière
paramètre qui indique à wxPython le nombre de pixels de bordure que vous souhaitez entourer le widget. le données d'utilisateur
Le paramètre est utilisé uniquement lorsque vous souhaitez effectuer une opération complexe avec le dimensionnement du widget et est en fait assez rare à voir dans la pratique.
L'ajout du bouton au calibreur suit exactement les mêmes étapes. Cependant, pour rendre les choses un peu plus intéressantes, je suis allé de l'avant et ai changé le wx.EXPAND
drapeau pour wx.CENTER
afin que le bouton soit centré à l'écran.
Lorsque vous exécutez cette version du code, votre application devrait ressembler à ceci:
Si vous souhaitez en savoir plus sur les calibreurs, la documentation de wxPython contient une belle page sur le sujet.
Ajout d'un événement
Bien que votre application semble plus intéressante visuellement, elle ne fait toujours rien. Par exemple, si vous appuyez sur le bouton, rien ne se passe vraiment.
Donnons un emploi au bouton:
importation wx
classe MyFrame(wx.Cadre):
def __init__(soi):
super().__init__(parent=Aucun, Titre='Bonjour le monde')
panneau = wx.Panneau(soi)
mon_sizer = wx.BoxSizer(wx.VERTICALE)
soi.text_ctrl = wx.TextCtrl(panneau)
mon_sizer.Ajouter(soi.text_ctrl, 0, wx.TOUT | wx.DÉVELOPPER, 5)
mon_btn = wx.Bouton(panneau, étiquette='Press Me')
mon_btn.Lier(wx.EVT_BUTTON, soi.on_press)
mon_sizer.Ajouter(mon_btn, 0, wx.TOUT | wx.CENTRE, 5)
panneau.SetSizer(mon_sizer)
soi.Spectacle()
def on_press(soi, un événement):
valeur = soi.text_ctrl.GetValue()
si ne pas valeur:
impression("Tu n'as rien entré!")
autre:
impression(F'Vous avez tapé: "valeur"')
si __prénom__ == '__principale__':
app = wx.App()
Cadre = MyFrame()
app.Boucle principale()
Les widgets de wxPython vous permettent de leur attacher des liaisons d’événements afin qu’ils puissent répondre à certains types d’événements.
Vous voulez que le bouton fasse quelque chose lorsque l'utilisateur appuie dessus. Vous pouvez y parvenir en appelant le bouton .Lier()
méthode. .Lier()
prend l'événement que vous souhaitez lier, le gestionnaire à appeler lorsque l'événement se produit, une source facultative et quelques identificateurs facultatifs.
Dans cet exemple, vous liez votre objet bouton à la wx.EVT_BUTTON
événement et lui dire d'appeler on_press ()
quand cet événement est renvoyé.
Un événement est "déclenché" lorsque l'utilisateur effectue l'événement auquel vous êtes lié. Dans ce cas, l’événement que vous configurez est l’événement de pression de bouton, wx.EVT_BUTTON
.
.on_press ()
accepte un deuxième argument que vous pouvez appeler un événement
. C'est par convention. Vous pouvez appeler cela autre chose si vous le souhaitez. Cependant, le paramètre event fait ici référence au fait que, lorsque cette méthode est appelée, son deuxième argument doit être un objet événement.
Dans .on_press ()
, vous pouvez obtenir le contenu du contrôle de texte en appelant son GetValue ()
méthode. Vous imprimez ensuite une chaîne sur stdout en fonction du contenu du contrôle de texte.
Maintenant que vous en avez terminé avec les bases, apprenons à créer une application qui fasse quelque chose d’utile!
Création d'une application opérationnelle
La première étape pour créer quelque chose de nouveau consiste à déterminer ce que vous voulez créer. Dans ce cas, je me suis permis de prendre cette décision pour vous. Vous allez apprendre à créer un éditeur de balises MP3! La prochaine étape lors de la création de quelque chose de nouveau consiste à déterminer quels packages peuvent vous aider à accomplir votre tâche.
Si vous effectuez une recherche Google pour Marquage mp3 Python
, vous trouverez que vous avez plusieurs options:
J'ai essayé quelques-uns d'entre eux et j'ai décidé que eyeD3 eu une belle API que vous pouviez utiliser sans vous enliser avec les spécifications MP3 de l’ID3. Vous pouvez installer eyeD3 en utilisant pépin
, comme ça:
Lors de l’installation de ce paquet sur macOS, vous devrez peut-être installer libmagic
en utilisant brasser
. Les utilisateurs Windows et Linux ne devraient pas avoir de problèmes d’installation de eyeD3.
Conception de l'interface utilisateur
Lorsqu’il s’agit de concevoir une interface, il est toujours agréable d’écrire à quoi devrait ressembler l’interface utilisateur.
Vous devrez être capable de faire ce qui suit:
- Ouvrir un ou plusieurs fichiers MP3
- Afficher les tags MP3 actuels
- Modifier une balise MP3
La plupart des interfaces utilisateur utilisent un menu ou un bouton pour ouvrir des fichiers ou des dossiers. Vous pouvez aller avec un Fichier menu pour cela. Comme vous voudrez probablement voir les tags de plusieurs fichiers MP3, vous devrez trouver un widget capable de le faire de manière agréable.
Quelque chose de tabulaire avec des colonnes et des rangées serait idéal car vous pouvez alors avoir des colonnes étiquetées pour les balises MP3. La boîte à outils wxPython contient quelques widgets qui fonctionneraient pour cela, les deux premiers étant les suivants:
Tu devrais utiliser wx.ListCtrl
dans ce cas comme la grille
widget est exagéré, et franchement, il est également un peu plus complexe. Enfin, vous avez besoin d’un bouton pour éditer la balise MP3 sélectionnée.
Maintenant que vous savez ce que vous voulez, vous pouvez le rédiger:
L'illustration ci-dessus nous donne une idée de l'apparence de l'application. Maintenant que vous savez ce que vous voulez faire, c’est le moment de coder!
Création de l'interface utilisateur
Il existe de nombreuses approches différentes pour écrire une nouvelle application. Par exemple, devez-vous suivre le modèle de conception Model-View-Controller? Comment divisez-vous les cours? Une classe par fichier? Il existe de nombreuses questions de ce type, et plus vous maîtriserez la conception d’interface graphique, plus vous saurez comment vous souhaitez y répondre.
Dans votre cas, vous n'avez vraiment besoin que de deux cours:
- UNE
wx.Panel
classe - UNE
wx.Frame
classe
Vous pouvez également plaider en faveur de la création d’un module de type contrôleur, mais vous n’en avez vraiment pas besoin. Vous pouvez également plaider en faveur de chaque classe dans son propre module, mais pour rester compact, vous créerez un fichier Python unique pour tout votre code.
Commençons par les importations et la classe de panneaux:
importation eyed3
importation glob
importation wx
classe Mp3Panel(wx.Panneau):
def __init__(soi, parent):
super().__init__(parent)
main_sizer = wx.BoxSizer(wx.VERTICALE)
soi.row_obj_dict =
soi.list_ctrl = wx.ListCtrl(
soi, Taille=(-1, 100),
style=wx.LC_REPORT | wx.BORDER_SUNKEN
)
soi.list_ctrl.InsertColumn(0, 'Artiste', largeur=140)
soi.list_ctrl.InsertColumn(1, 'Album', largeur=140)
soi.list_ctrl.InsertColumn(2, 'Titre', largeur=200)
main_sizer.Ajouter(soi.list_ctrl, 0, wx.TOUT | wx.DÉVELOPPER, 5)
edit_button = wx.Bouton(soi, étiquette='Modifier')
edit_button.Lier(wx.EVT_BUTTON, soi.on_edit)
main_sizer.Ajouter(edit_button, 0, wx.TOUT | wx.CENTRE, 5)
soi.SetSizer(main_sizer)
def on_edit(soi, un événement):
impression('in on_edit')
def update_mp3_listing(soi, folder_path):
impression(folder_path)
Ici, vous importez le eyed3
paquet, Python glob
paquet, et le wx
package pour votre interface utilisateur. Ensuite, vous sous-classe wx.Panel
et créez votre interface utilisateur. Vous avez besoin d’un dictionnaire pour stocker des données sur vos MP3, que vous pouvez nommer. row_obj_dict
.
Ensuite, vous créez un wx.ListCtrl
et le mettre en mode rapport (wx.LC_REPORT
) avec une bordure creuse (wx.BORDER_SUNKEN
). Le contrôle de liste peut prendre quelques autres formes en fonction du drapeau de style que vous transmettez, mais le drapeau de rapport est le plus populaire.
Pour faire le ListCtrl
avoir les en-têtes corrects, vous devrez appeler .InsertColumn ()
pour chaque en-tête de colonne. Vous fournissez ensuite l'index de la colonne, son étiquette et sa largeur en pixels.
La dernière étape consiste à ajouter votre modifier
bouton, un gestionnaire d'événements et une méthode. Vous pouvez créer la liaison à l'événement et laisser la méthode qu'elle appelle vide pour l'instant.
Maintenant, vous devriez écrire le code pour le cadre:
classe Mp3Frame(wx.Cadre):
def __init__(soi):
super().__init__(parent=Aucun,
Titre='Mp3 Tag Editor')
soi.panneau = Mp3Panel(soi)
soi.Spectacle()
si __prénom__ == '__principale__':
app = wx.App(Faux)
Cadre = Mp3Frame()
app.Boucle principale()
Cette classe est beaucoup plus simple que la première en ce sens que tout ce que vous avez à faire est de définir le titre du cadre et d’instancier la classe du panneau. Mp3Panel
. Lorsque vous avez tous terminé, votre interface utilisateur devrait ressembler à ceci:
L’interface utilisateur semble presque correcte, mais vous n’avez pas de Fichier menu. Cela rend impossible l'ajout de fichiers MP3 à l'application et la modification de leurs balises!
Laissez-nous réparer cela maintenant.
Faire une application qui fonctionne
La première étape pour que votre application fonctionne consiste à mettre à jour l’application afin qu’elle ait une Fichier menu car alors vous pouvez ajouter des fichiers MP3 à votre création. Les menus sont presque toujours ajoutés aux wx.Frame
classe, donc c'est la classe que vous devez modifier.
Remarque: Certaines applications ont cessé d'utiliser des menus dans leurs applications. Microsoft Office a été l'un des premiers à le faire lorsqu'il a ajouté le ruban. La boîte à outils wxPython a un widget personnalisé que vous pouvez utiliser pour créer des rubans dans wx.lib.agw.ribbon
.
Les navigateurs Web, tels que Google Chrome et Mozilla Firefox, constituent l’autre type d’application qui a récemment supprimé des menus. Ils utilisent simplement les barres d'outils de nos jours.
Apprenons comment ajouter une barre de menus à notre application:
classe Mp3Frame(wx.Cadre):
def __init__(soi):
wx.Cadre.__init__(soi, parent=Aucun,
Titre='Mp3 Tag Editor')
soi.panneau = Mp3Panel(soi)
soi.create_menu()
soi.Spectacle()
def create_menu(soi):
barre de menu = wx.Barre de menu()
Menu Fichier = wx.Menu()
open_folder_menu_item = Menu Fichier.Ajouter(
wx.ID_ANY, 'Dossier ouvert',
'Ouvrir un dossier avec des MP3'
)
barre de menu.Ajouter(Menu Fichier, '&Fichier')
soi.Lier(
un événement=wx.EVT_MENU,
gestionnaire=soi.on_open_folder,
la source=open_folder_menu_item,
)
soi.SetMenuBar(barre de menu)
def on_open_folder(soi, un événement):
Titre = "Choisissez un répertoire:"
dlg = wx.DirDialog(soi, Titre,
style=wx.DD_DEFAULT_STYLE)
si dlg.ShowModal() == wx.ID_OK:
soi.panneau.update_mp3_listing(dlg.GetPath())
dlg.Détruire()
Ici, vous ajoutez un appel à .create_menu ()
dans le constructeur de la classe. Puis dans .create_menu ()
lui-même, vous allez créer un wx.MenuBar
exemple et un wx.Menu
exemple.
Pour ajouter un élément de menu à un menu, appelez l’instance de menu suivante. .Ajouter()
et passez le suivant:
- Un identifiant unique
- Le libellé du nouvel élément de menu
- Une chaîne d'aide
Ensuite, vous devez ajouter le menu à la barre de menu. Vous devrez donc appeler le menu de la barre de menu. .Ajouter()
. Il prend l'instance de menu et l'étiquette pour le menu. Cette étiquette est un peu étrange en ce que vous l'avez appelé &Fichier
au lieu de Fichier
. La perluète indique à wxPython de créer un raccourci clavier de Alt+F ouvrir le Fichier
menu en utilisant seulement votre clavier.
Remarque: Si vous souhaitez ajouter des raccourcis clavier à votre application, vous souhaiterez utiliser une instance de wx.AcceleratorTable
pour les créer. Vous pouvez en savoir plus sur les tables Accerator dans la documentation de wxPython.
Pour créer une liaison d'événement, vous devez appeler self.Bind ()
, qui lie le cadre à wx.EVT_MENU
. Quand vous utilisez self.Bind ()
pour un événement de menu, vous devez non seulement indiquer à wxPython lequel gestionnaire
à utiliser, mais aussi qui la source
pour lier le gestionnaire à.
Enfin, vous devez appeler le .SetMenuBar ()
et passez l'instance de la barre de menu pour qu'elle soit montrée à l'utilisateur.
Maintenant que le menu est ajouté à votre cadre, passons au gestionnaire d’événements de l’élément de menu, qui est reproduit ci-dessous:
def on_open_folder(soi, un événement):
Titre = "Choisissez un répertoire:"
dlg = wx.DirDialog(soi, Titre, style=wx.DD_DEFAULT_STYLE)
si dlg.ShowModal() == wx.ID_OK:
soi.panneau.update_mp3_listing(dlg.GetPath())
dlg.Détruire()
Puisque vous voulez que l’utilisateur choisisse un dossier contenant des fichiers MP3, vous voudrez utiliser les fichiers de wxPython. wx.DirDialog
. le wx.DirDialog
permet à l'utilisateur d'ouvrir uniquement des répertoires.
Vous pouvez définir le titre de la boîte de dialogue et divers indicateurs de style. Pour afficher la boîte de dialogue, vous devez appeler .ShowModal ()
. La boîte de dialogue s'affichera de manière modale, ce qui signifie que l'utilisateur ne pourra pas interagir avec votre application principale tant que la boîte de dialogue sera affichée.
Si l’utilisateur appuie sur le bouton D'accord bouton, vous pouvez obtenir le choix du chemin de l’utilisateur via le dialogue .GetPath ()
. Vous voudrez transmettre ce chemin à votre classe de panel, ce que vous pouvez faire ici en appelant le .update_mp3_listing ()
.
Enfin, vous devez fermer la boîte de dialogue. Pour fermer une boîte de dialogue, la méthode recommandée consiste à appeler son .Détruire()
.
Les dialogues ont un .Fermer()
méthode, mais cela ne fait que masquer la boîte de dialogue et elle ne se détruira pas lorsque vous fermerez votre application, ce qui peut entraîner des problèmes étranges, tels que la fermeture de votre application. C’est plus simple d’appeler .Détruire()
dans la boîte de dialogue pour éviter ce problème.
Maintenant, mettons à jour votre Mp3Panel
classe. Vous pouvez commencer par mettre à jour .update_mp3_listing ()
:
def update_mp3_listing(soi, folder_path):
soi.chemin_fichier_current = folder_path
soi.list_ctrl.Tout effacer()
soi.list_ctrl.InsertColumn(0, 'Artiste', largeur=140)
soi.list_ctrl.InsertColumn(1, 'Album', largeur=140)
soi.list_ctrl.InsertColumn(2, 'Titre', largeur=200)
soi.list_ctrl.InsertColumn(3, 'Année', largeur=200)
mp3s = glob.glob(folder_path + '/*.mp3')
mp3_objects = []
indice = 0
pour mp3 dans mp3s:
mp3_object = eyed3.charge(mp3)
soi.list_ctrl.InsertItem(indice,
mp3_object.étiquette.artiste)
soi.list_ctrl.SetItem(indice, 1,
mp3_object.étiquette.album)
soi.list_ctrl.SetItem(indice, 2,
mp3_object.étiquette.Titre)
mp3_objects.ajouter(mp3_object)
soi.row_obj_dict[[[[indice] = mp3_object
indice + = 1
Ici, vous définissez le répertoire actuel sur le dossier spécifié, puis vous effacez le contrôle de liste. Ceci garde le contrôle de liste frais et affiche uniquement les fichiers MP3 sur lesquels vous travaillez actuellement. Cela signifie également que vous devez réinsérer toutes les colonnes.
Ensuite, vous voudrez prendre le dossier qui a été transmis et utiliser le glob
module pour rechercher des fichiers MP3.
Ensuite, vous pouvez passer en boucle sur les MP3 et les transformer en eyed3
objets. Vous pouvez le faire en appelant le .charge()
de eyed3
. En supposant que les MP3 possèdent déjà les balises appropriées, vous pouvez ensuite ajouter l'artiste, l'album et le titre du MP3 au contrôle de liste.
Fait intéressant, la méthode permettant d’ajouter une nouvelle ligne à un objet de contrôle de liste consiste à appeler .InsertItem ()
pour la première colonne et SetItem ()
pour toutes les colonnes suivantes.
La dernière étape consiste à enregistrer votre objet MP3 dans votre dictionnaire Python, row_obj_dict
.
Maintenant, vous devez mettre à jour le .on_edit ()
gestionnaire d’événements pour que vous puissiez éditer les tags d’un MP3:
def on_edit(soi, un événement):
sélection = soi.list_ctrl.GetFocusedItem()
si sélection > = 0:
mp3 = soi.row_obj_dict[[[[sélection]
dlg = EditDialog(mp3)
dlg.ShowModal()
soi.update_mp3_listing(soi.chemin_fichier_current)
dlg.Détruire()
La première chose à faire est d’obtenir la sélection de l’utilisateur en appelant le service de contrôle de liste. .GetFocusedItem ()
.
Si l'utilisateur n'a rien sélectionné dans le contrôle de liste, il retournera -1
. En supposant que l'utilisateur ait sélectionné quelque chose, vous souhaiterez extraire l'objet MP3 de votre dictionnaire et ouvrir une boîte de dialogue de l'éditeur de balises MP3. Ce sera une boîte de dialogue personnalisée que vous utiliserez pour éditer les balises artiste, album et titre du fichier MP3.
Comme d'habitude, affichez le dialogue de manière modale. Lorsque la boîte de dialogue se ferme, les deux dernières lignes de .on_edit ()
va exécuter. Ces deux lignes mettront à jour le contrôle de liste pour qu'il affiche les informations de balise MP3 actuelles que l'utilisateur vient de modifier et détruira la boîte de dialogue.
Création d'un dialogue d'édition
La dernière pièce du puzzle consiste à créer une boîte de dialogue d’édition de balises MP3. Par souci de brièveté, nous allons ignorer l'esquisse de cette interface car il s'agit d'une série de lignes contenant des étiquettes et des contrôles de texte. Les commandes de texte doivent contenir les informations de balise existantes préremplies. Vous pouvez créer une étiquette pour les contrôles de texte en créant des instances de wx.StaticText
.
Lorsque vous devez créer une boîte de dialogue personnalisée, le wx.Dialog
la classe est votre ami. Vous pouvez l'utiliser pour concevoir l'éditeur:
classe EditDialog(wx.Dialogue):
def __init__(soi, mp3):
Titre = F'Édition "mp3.tag.title"'
super().__init__(parent=Aucun, Titre=Titre)
soi.mp3 = mp3
soi.main_sizer = wx.BoxSizer(wx.VERTICALE)
soi.artiste = wx.TextCtrl(
soi, valeur=soi.mp3.étiquette.artiste)
soi.add_widgets('Artiste', soi.artiste)
soi.album = wx.TextCtrl(
soi, valeur=soi.mp3.étiquette.album)
soi.add_widgets('Album', soi.album)
soi.Titre = wx.TextCtrl(
soi, valeur=soi.mp3.étiquette.Titre)
soi.add_widgets('Title', soi.Titre)
btn_sizer = wx.BoxSizer()
save_btn = wx.Button(soi, étiquette='Save')
save_btn.Bind(wx.EVT_BUTTON, soi.on_save)
btn_sizer.Ajouter(save_btn, 0, wx.ALL, 5)
btn_sizer.Ajouter(wx.Button(
soi, identifiant=wx.ID_CANCEL), 0, wx.ALL, 5)
soi.main_sizer.Ajouter(btn_sizer, 0, wx.CENTER)
soi.SetSizer(soi.main_sizer)
Here you want to start off by sub-classing wx.Dialog
and giving it a custom title based on the title of the MP3 that you are editing.
Next you can create the sizer you want to use and the widgets. To make things easier, you can create a helper method called .add_widgets()
for adding the wx.StaticText
widgets as rows with the text control instances. The only other widget here is the sauvegarder button.
Let’s write the add_widgets
method next:
def add_widgets(soi, label_text, text_ctrl):
row_sizer = wx.BoxSizer(wx.HORIZONTAL)
étiquette = wx.StaticText(soi, étiquette=label_text,
Taille=(50, -1))
row_sizer.Ajouter(étiquette, 0, wx.ALL, 5)
row_sizer.Ajouter(text_ctrl, 1, wx.ALL | wx.EXPAND, 5)
soi.main_sizer.Ajouter(row_sizer, 0, wx.EXPAND)
add_widgets()
takes the label’s text and the text control instance. It then creates a horizontally oriented BoxSizer
.
Next you will create an instance of wx.StaticText
using the passed-in text for its label parameter. You will also set its size to be 50
pixels wide and the default height is set with a -1
. Since you want the label before the text control, you will add the StaticText widget to your BoxSizer first and then add the text control .
Finally, you want to add the horizontal sizer to the top level vertical sizer. By nesting the sizers in each other, you can design complex applications.
Now you will need to create the on_save()
event handler so that you can save your changes:
def on_save(soi, un événement):
soi.mp3.étiquette.artiste = soi.artiste.GetValue()
soi.mp3.étiquette.album = soi.album.GetValue()
soi.mp3.étiquette.Titre = soi.Titre.GetValue()
soi.mp3.étiquette.enregistrer()
soi.Close()
Here you set the tags to the contents of the text controls and then call the eyed3
object’s .save()
. Finally, you call the .Close()
of the dialog. The reason you call .Close()
here instead of .Destroy()
is that you already call .Destroy()
dans le .on_edit()
of your panel subclass.
Now your application is complete!
Conclusion
You learned a lot about wxPython in this article. You became familiar with the basics of creating GUI applications using wxPython.
You now know more about the following:
- How to work with some of wxPython’s widgets
- How events work in wxPython
- How absolute positioning compares with sizers
- How to create a skeleton application
Finally you learned how to create a working application, an MP3 tag editor. You can use what you learned in this article to continue to enhance this application or perhaps create an amazing application on your own.
The wxPython GUI toolkit is robust and full of interesting widgets that you can use to build cross-platform applications. You are limited by only your imagination.
Lectures complémentaires
If you would like to learn more about wxPython, you can check out some of the following links:
For more information on what else you can do with Python, you might want to check out What Can I Do with Python? If you’d like to learn more about Python’s super()
, then Supercharge Your Classes With Python super() may be just right for you.
You can also download the code for the MP3 tag editor application that you created in this article if you want to study it more in depth.
[ad_2]