Comment rédiger un éditeur de texte simple dans PYQT5

Comment rédiger un éditeur de texte simple dans PYQT5
Cet article couvrira un guide sur la création d'un éditeur de texte simple dans Python3 et Pyqt5. QT5 est un ensemble de bibliothèques multiplateformes écrites en C ++, utilisée principalement pour créer des applications graphiques riches. PYQT5 fournit des liaisons Python pour la dernière version de QT5. Tous les échantillons de code de cet article sont testés avec Python 3.8.2 et pyqt5 version 5.14.1 sur Ubuntu 20.04.

Installation de Pyqt5 dans Linux

Pour installer Pyqt5 dans la dernière version d'Ubuntu, exécutez la commande ci-dessous:

$ sudo apt installer python3-pyqt5

Si vous utilisez une autre distribution Linux, recherchez le terme «pyqt5» dans le gestionnaire de packages et installez-le à partir de là. Alternativement, vous pouvez installer PYQT5 à partir de PIP Package Manager en utilisant la commande ci-dessous:

$ pip install pyqt5

Notez que dans certaines distributions, vous devrez peut-être utiliser la commande PIP3 pour installer correctement Pyqt5.

Code complet

Je publie du code complet à l'avance afin que vous puissiez mieux comprendre le contexte pour les extraits de code individuels expliqués plus loin dans l'article. Si vous connaissez Python et Pyqt5, vous pouvez simplement vous référer au code ci-dessous et sauter l'explication.

#!/ usr / bin / env python3
importer sys
de pyqt5.Qtwidgets import Qwidget, qapplication, qvboxlayout, qhboxlayout
de pyqt5.QtWidgets Import Qtextedit, QLabel, Qshortcut, QFiledialog, QMessageBox
de pyqt5.Qtgui import Qkeysence
à partir de Pyqt5 Import Qt
Fenêtre de classe (Qwidget):
def __init __ (soi):
super().__init __ ()
soi.file_path = aucun
soi.open_new_file_shortcut = qshortcut (qkeysence ('ctrl + o'), self)
soi.open_new_file_shortcut.activé.se connecter (soi.open_new_file)
soi.Save_current_file_shortcut = qshortcut (QKeySequence ('Ctrl + S'), self)
soi.sauvegarder_current_file_shortcut.activé.se connecter (soi.Save_current_file)
vbox = qvboxlayout ()
text = "fichier sans titre"
soi.Titre = QLabel (texte)
soi.titre.setwordwrap (true)
soi.titre.setalignment (QT.QT.AlignCenter)
vox.addWidget (soi.titre)
soi.setLayout (VBox)
soi.scrollable_text_area = qtextedit ()
vox.addWidget (soi.scrollable_text_area)
def open_new_file (self):
soi.file_path, filter_type = qfilediAnog.getOpenFileName (self, "ouvrir un nouveau fichier",
"", "Tous les fichiers (*)")
Si vous-même.chemin du fichier:
avec ouvert (soi.file_path, "r") comme f:
file_contents = f.lire()
soi.titre.setText (soi.chemin du fichier)
soi.scrollable_text_area.setText (file_contents)
autre:
soi.invalid_path_alert_message ()
def Save_Current_file (self):
Si ce n'est pas soi.chemin du fichier:
new_file_path, filter_type = qfiledialogique.getSaveFileName (self, "Enregistrer ce fichier
comme… "," "," tous les fichiers (*) ")
Si new_file_path:
soi.file_path = new_file_path
autre:
soi.invalid_path_alert_message ()
retourner faux
file_contents = self.scrollable_text_area.toplainText ()
avec ouvert (soi.file_path, "w") comme f:
F.écrire (file_contents)
soi.titre.setText (soi.chemin du fichier)
Def CloseEvent (self, événement):
MessageBox = qMessageBox ()
title = "Quitte Application?"
message = "Avertissement !!\ n \ nif vous quittez sans enregistrer, toute modification apportée au fichier
sera perdu.Fichier \ n \ nsave avant de quitter?"
Répondre = Messagebox.Question (Self, titre, message, Messagebox.Oui | messagerie.Non |
messagerie.Annuler, Messagebox.Annuler)
Si Répondre == Messagebox.Oui:
return_value = self.Save_current_file ()
Si return_value == false:
événement.ignorer()
ELIF Répondre == Messagebox.Non:
événement.accepter()
autre:
événement.ignorer()
def invalid_path_alert_message (self):
MessageBox = qMessageBox ()
messagerie.setWindowTitle ("fichier non valide")
messagerie.setText ("le nom de fichier ou le chemin sélectionné n'est pas valide. Veuillez sélectionner un
fichier valide.")
messagerie.exec ()
Si __Name__ == '__MAIN__':
app = qapplication (sys.argv)
w = window ()
w.showMaximized ()
système.sortir (application.exec_ ())

Explication

La première partie du code importe des modules qui seront utilisés dans tout l'échantillon:

importer sys
de pyqt5.Qtwidgets import Qwidget, qapplication, qvboxlayout, qhboxlayout
de pyqt5.QtWidgets Import Qtextedit, QLabel, Qshortcut, QFiledialog, QMessageBox
de pyqt5.Qtgui import Qkeysence
à partir de Pyqt5 Import Qt

Dans la partie suivante, une nouvelle classe appelée «Window» est créée qui hérite de la classe «Qwidget». La classe QWidget fournit des composants graphiques couramment utilisés dans QT. En utilisant «super», vous pouvez vous assurer que l'objet QT parent est renvoyé.

Fenêtre de classe (Qwidget):
def __init __ (soi):
super().__init __ ()

Certaines variables sont définies dans la partie suivante. Le chemin du fichier est défini sur «Aucun» par défaut et les raccourcis pour ouvrir un fichier à l'aide et l'enregistrement d'un fichier en utilisant sont définis à l'aide de la classe QShortcut. Ces raccourcis sont ensuite connectés à leurs méthodes respectives qui sont appelées chaque fois qu'un utilisateur appuie sur les combinaisons de touches définies.

soi.file_path = aucun
soi.open_new_file_shortcut = qshortcut (qkeysence ('ctrl + o'), self)
soi.open_new_file_shortcut.activé.se connecter (soi.open_new_file)
soi.Save_current_file_shortcut = qshortcut (QKeySequence ('Ctrl + S'), self)
soi.sauvegarder_current_file_shortcut.activé.se connecter (soi.Save_current_file)

À l'aide de la classe QVBoxLayout, une nouvelle mise en page est créée à laquelle les widgets enfants seront ajoutés. Une étiquette alignée centrale est définie pour le nom de fichier par défaut à l'aide de la classe QLabel.

vbox = qvboxlayout ()
text = "fichier sans titre"
soi.Titre = QLabel (texte)
soi.titre.setwordwrap (true)
soi.titre.setalignment (QT.QT.AlignCenter)
vox.addWidget (soi.titre)
soi.setLayout (VBox)

Ensuite, une zone de texte est ajoutée à la mise en page à l'aide d'un objet Qtextedit. Le widget Qtextedit vous donnera une zone modifiable et déficient pour travailler avec. Ce widget prend en charge la copie typique, coller, couper, annuler, refaire, select-all, etc. Raccourcis clavier. Vous pouvez également utiliser un menu contextuel de clic droit dans la zone de texte.

soi.scrollable_text_area = qtextedit ()
vox.addWidget (soi.scrollable_text_area)

La méthode «Open_NEW_FIE» est appelée lorsqu'un utilisateur termine le raccourci clavier. La classe QFiledialog présente une boîte de dialogue de sélecteur de fichiers à l'utilisateur. Le chemin du fichier est déterminé après qu'un utilisateur a sélectionné un fichier dans le sélecteur. Si le chemin du fichier est valide, le contenu texte est lu à partir du fichier et défini sur le widget Qtextedit. Cela rend le texte visible pour l'utilisateur, modifie le titre en nouveau nom de fichier et termine le processus d'ouverture d'un nouveau fichier. Si, pour une raison quelconque, le chemin du fichier ne peut pas être déterminé, une boîte d'alerte «fichier non valide» est affichée à l'utilisateur.

def open_new_file (self):
soi.file_path, filter_type = qfilediAnog.getOpenFileName (self, "ouvrir un nouveau fichier", "",
"Tous les fichiers (*)")
Si vous-même.chemin du fichier:
avec ouvert (soi.file_path, "r") comme f:
file_contents = f.lire()
soi.titre.setText (soi.chemin du fichier)
soi.scrollable_text_area.setText (file_contents)
autre:
soi.invalid_path_alert_message ()

La méthode "Save_Current_File" est appelée chaque fois qu'un utilisateur termine le raccourci clavier. Au lieu de récupérer un nouveau chemin de fichier, QFiledialog demande maintenant à l'utilisateur de fournir un chemin. Si le chemin du fichier est valide, le contenu visible dans le widget Qtextedit est écrit sur le chemin d'alerte complet, sinon un boîtier d'alerte «fichier non valide» est affiché. Le titre du fichier actuellement en cours de modification est également modifié pour le nouvel emplacement fourni par l'utilisateur.

def Save_Current_file (self):
Si ce n'est pas soi.chemin du fichier:
new_file_path, filter_type = qfiledialogique.getSaveFileName (self, "Enregistrer ce fichier
comme… "," "," tous les fichiers (*) ")
Si new_file_path:
soi.file_path = new_file_path
autre:
soi.invalid_path_alert_message ()
retourner faux
file_contents = self.scrollable_text_area.toplainText ()
avec ouvert (soi.file_path, "w") comme f:
F.écrire (file_contents)
soi.titre.setText (soi.chemin du fichier)

La méthode «CloseEvent» fait partie de l'API de gestion des événements PYQT5. Cette méthode est appelée chaque fois qu'un utilisateur essaie de fermer une fenêtre à l'aide du bouton croisé ou en appuyant sur la combinaison de clé. Lors du licenciement de l'événement proche, l'utilisateur est affiché une boîte de dialogue avec trois choix: «Oui», «Non» et «Annuler». Le bouton «Oui» enregistre le fichier et ferme la demande tandis que le bouton «non» ferme le fichier sans enregistrer le contenu. Le bouton «Annuler» ferme la boîte de dialogue et ramène l'utilisateur à l'application.

Def CloseEvent (self, événement):
MessageBox = qMessageBox ()
title = "Quitte Application?"
message = "Avertissement !!\ n \ nif vous quittez sans enregistrer, toute modification apportée au fichier
être perdu.Fichier \ n \ nsave avant de quitter?"
Répondre = Messagebox.Question (Self, titre, message, Messagebox.Oui | messagerie.Non |
messagerie.Annuler, Messagebox.Annuler)
Si Répondre == Messagebox.Oui:
return_value = self.Save_current_file ()
Si return_value == false:
événement.ignorer()
ELIF Répondre == Messagebox.Non:
événement.accepter()
autre:
événement.ignorer()

La boîte d'alerte «Fichier non valide» n'a pas de cloches et de sifflets. Il transmet simplement le message que le chemin du fichier n'a pas pu être déterminé.

def invalid_path_alert_message (self):
MessageBox = qMessageBox ()
messagerie.setWindowTitle ("fichier non valide")
messagerie.setText ("le nom de fichier ou le chemin sélectionné n'est pas valide. Veuillez sélectionner un fichier valide.")
messagerie.exec ()

Enfin, la boucle d'application principale pour la gestion des événements et le dessin de widgets sont démarrées en utilisant le «.exec_ () ”Méthode.

Si __Name__ == '__MAIN__':
app = qapplication (sys.argv)
w = window ()
w.showMaximized ()
système.sortir (application.exec_ ())

Exécution de l'application

Enregistrez simplement le code complet dans un fichier texte, définissez l'extension de fichier sur «.py ", marquez le fichier exécutable et exécutez-le pour lancer l'application. Par exemple, si le nom du fichier est «Simple_text_editor.py ", vous devez exécuter les deux commandes en suivant:

$ chmod + x simple_text_editor.py
$ ./ simple_text_editor.py

Des choses que vous pouvez faire pour améliorer le code

Le code expliqué ci-dessus fonctionne bien pour un éditeur de texte à nu. Cependant, il peut ne pas être utile à des fins pratiques car il manque de nombreuses fonctionnalités couramment vues dans les bons éditeurs de texte. Vous pouvez améliorer le code en ajoutant de nouvelles fonctionnalités telles que les numéros de ligne, la mise en évidence en ligne, la surlimination de la syntaxe, les onglets multiples, l'enregistrement de session, la barre d'outils, les menus déroulants, la détection de modification de tampon, etc.

Conclusion

Cet article se concentre principalement sur la fourniture d'un terrain de départ pour créer des applications PYQT. Si vous trouvez des erreurs dans le code ou souhaitez suggérer quelque chose, les commentaires sont les bienvenus.