Python

Een eenvoudige teksteditor schrijven in PyQt5t

Een eenvoudige teksteditor schrijven in PyQt5t
Dit artikel behandelt een handleiding voor het maken van een eenvoudige teksteditor in Python3 en PyQt5. Qt5 is een set platformonafhankelijke bibliotheken geschreven in C++, voornamelijk gebruikt voor het maken van rijke grafische toepassingen graphic. PyQt5 biedt Python-bindingen voor de nieuwste versie van Qt5. Alle codevoorbeelden in dit artikel zijn getest met Python 3.8.2 en PyQt5 versie 5.14.1 op Ubuntu 20.04.

PyQt5 installeren in Linux

Voer de onderstaande opdracht uit om PyQt5 in de nieuwste versie van Ubuntu te installeren:

$ sudo apt install python3-pyqt5

Als u een andere Linux-distributie gebruikt, zoekt u naar de term "Pyqt5" ​​in de pakketbeheerder en installeert u deze vanaf daar. Als alternatief kunt u PyQt5 installeren vanuit pip package manager met behulp van de onderstaande opdracht:

$ pip installeer pyqt5

Merk op dat je in sommige distributies mogelijk de pip3-opdracht moet gebruiken om PyQt5 correct te installeren.

Volledige code

Ik plaats van tevoren volledige code, zodat u de context voor afzonderlijke codefragmenten die later in het artikel wordt uitgelegd, beter kunt begrijpen. Als je bekend bent met Python en PyQt5, kun je gewoon naar de onderstaande code verwijzen en de uitleg overslaan.

#!/usr/bin/env python3
import systeem
van PyQt5.QtWidgets importeert QWidget, QApplication, QVBoxLayout, QHBoxLayout
van PyQt5.QtWidgets importeert QTextEdit, QLabel, QShortcut, QFileDialog, QMessageBox
van PyQt5.QtGui QKeySequence importeren
van PyQt5 import Qt
klasse Venster (QWidget):
def __init__(zelf):
super().__in het__()
zelf.file_path = Geen
zelf.open_new_file_shortcut = QShortcut(QKeySequence('Ctrl+O'), zelf)
zelf.open_new_file_shortcut.geactiveerd.verbinden (zelf).open_new_file)
zelf.save_current_file_shortcut = QShortcut(QKeySequence('Ctrl+S'), zelf)
zelf.save_current_file_shortcut.geactiveerd.verbinden (zelf).save_current_file)
vbox = QVBoxLayout()
text = "Naamloos bestand"
zelf.titel = QLabel(tekst)
zelf.titel.setWordWrap(True)
zelf.titel.setAlignment(Qt.Qt.Tekst in het midden uitlijnen)
vbox.addWidget(zelf).titel)
zelf.setlay-out (vbox)
zelf.scrollable_text_area = QTextEdit()
vbox.addWidget(zelf).scrollable_text_area)
def open_new_file(zelf):
zelf.file_path, filter_type = QFileDialog.getOpenFileName(self, "Open nieuw bestand",
"", "Alle bestanden (*)")
als zelf.bestandspad:
met open(zelf).file_path, "r") als f:
file_contents = f.lezen()
zelf.titel.setText(zelf).bestandspad)
zelf.scrollable_text_area.setText(file_contents)
anders:
zelf.invalid_path_alert_message()
def save_current_file(zelf):
zo niet zelf.bestandspad:
new_file_path, filter_type = QFileDialog.getSaveFileName(self, "Sla dit bestand op"
als… ", "", "Alle bestanden (*)")
indien nieuw_bestandspad:
zelf.file_path = nieuw_file_path
anders:
zelf.invalid_path_alert_message()
retourneer False
file_contents = zelf.scrollable_text_area.naarPlainText()
met open(zelf).file_path, "w") als f:
f.schrijven(file_contents)
zelf.titel.setText(zelf).bestandspad)
def closeEvent(zelf, evenement):
messageBox = QMessageBox()
title = "Applicatie afsluiten?"
message = "WAARSCHUWING !!\n\nAls u afsluit zonder op te slaan, worden eventuele wijzigingen in het bestand
zal verloren gaan.\n\nBestand opslaan voordat u afsluit?"
reply = messageBox.vraag (zelf, titel, bericht, messageBox).Ja | berichten box.Nee |
berichten box.Annuleren, messageBox.Annuleren)
if reply == messageBox.Ja:
return_value = zelf.save_current_file()
if return_value == Onwaar:
evenement.negeren()
elif reply == messageBox.Nee:
evenement.aanvaarden()
anders:
evenement.negeren()
def invalid_path_alert_message(self):
messageBox = QMessageBox()
berichten box.setWindowTitle("Ongeldig bestand")
berichten box.setText("Geselecteerde bestandsnaam of pad is niet geldig. Selecteer a.u.b
geldig bestand.")
berichten box.exec()
if __name__ == '__main__':
app = QApplicatie(sys.argv)
w = Venster()
met wie.toon gemaximaliseerd()
sys.afsluiten (app.exec_())

Uitleg

Het eerste deel van de code importeert alleen modules die in het hele voorbeeld worden gebruikt:

import systeem
van PyQt5.QtWidgets importeert QWidget, QApplication, QVBoxLayout, QHBoxLayout
van PyQt5.QtWidgets importeert QTextEdit, QLabel, QShortcut, QFileDialog, QMessageBox
van PyQt5.QtGui QKeySequence importeren
van PyQt5 import Qt

In het volgende deel wordt een nieuwe klasse met de naam "Window" gemaakt die erft van de klasse "QWidget". De klasse QWidget biedt veelgebruikte grafische componenten in Qt. Door "super" te gebruiken, kunt u ervoor zorgen dat het bovenliggende Qt-object wordt geretourneerd.

klasse Venster (QWidget):
def __init__(zelf):
super().__in het__()

Sommige variabelen worden gedefinieerd in het volgende deel. Bestandspad is standaard ingesteld op "Geen" en snelkoppelingen voor het openen van een bestand met en een bestand opslaan met worden gedefinieerd met behulp van QShortcut class. Deze snelkoppelingen zijn vervolgens verbonden met hun respectievelijke methoden die worden aangeroepen wanneer een gebruiker op de gedefinieerde toetsencombinaties drukt.

zelf.file_path = Geen
zelf.open_new_file_shortcut = QShortcut(QKeySequence('Ctrl+O'), zelf)
zelf.open_new_file_shortcut.geactiveerd.verbinden (zelf).open_new_file)
zelf.save_current_file_shortcut = QShortcut(QKeySequence('Ctrl+S'), zelf)
zelf.save_current_file_shortcut.geactiveerd.verbinden (zelf).save_current_file)

Met de klasse QVBoxLayout wordt een nieuwe lay-out gemaakt waaraan onderliggende widgets worden toegevoegd. Er wordt een gecentreerd label ingesteld voor de standaard bestandsnaam met behulp van QLabel class.

vbox = QVBoxLayout()
text = "Naamloos bestand"
zelf.titel = QLabel(tekst)
zelf.titel.setWordWrap(True)
zelf.titel.setAlignment(Qt.Qt.Tekst in het midden uitlijnen)
vbox.addWidget(zelf).titel)
zelf.setlay-out (vbox)

Vervolgens wordt een tekstgebied toegevoegd aan de lay-out met behulp van een QTextEdit-object. De QTextEdit-widget geeft je een bewerkbaar, schuifbaar gebied om mee te werken. Deze widget ondersteunt typisch kopiëren, plakken, knippen, ongedaan maken, opnieuw uitvoeren, alles selecteren, enz. Toetsenbord sneltoetsen. U kunt ook een contextmenu met de rechtermuisknop gebruiken in het tekstgebied.

zelf.scrollable_text_area = QTextEdit()
vbox.addWidget(zelf).scrollable_text_area)

De methode "open_new_fie" wordt aangeroepen wanneer een gebruiker voltooit Toetsenbord sneltoets. De klasse QFileDialog presenteert een dialoogvenster voor het kiezen van bestanden aan de gebruiker. Het bestandspad wordt bepaald nadat een gebruiker een bestand uit de kiezer heeft geselecteerd. Als het bestandspad geldig is, wordt de tekstinhoud uit het bestand gelezen en ingesteld op de QTextEdit-widget. Dit maakt tekst zichtbaar voor de gebruiker, verandert de titel in de nieuwe bestandsnaam en voltooit het proces van het openen van een nieuw bestand. Als om de een of andere reden het bestandspad niet kan worden bepaald, wordt een waarschuwingsvenster voor "ongeldig bestand" weergegeven aan de gebruiker.

def open_new_file(zelf):
zelf.file_path, filter_type = QFileDialog.getOpenFileName(self, "Open nieuw bestand", "",
"Alle bestanden (*)")
als zelf.bestandspad:
met open(zelf).file_path, "r") als f:
file_contents = f.lezen()
zelf.titel.setText(zelf).bestandspad)
zelf.scrollable_text_area.setText(file_contents)
anders:
zelf.invalid_path_alert_message()

De methode "save_current_file" wordt aangeroepen wanneer een gebruiker voltooit Toetsenbord sneltoets. In plaats van een nieuw bestandspad op te halen, vraagt ​​QFileDialog de gebruiker nu om een ​​pad op te geven. Als het bestandspad geldig is, wordt de inhoud die zichtbaar is in de QTextEdit-widget geschreven naar het volledige bestandspad, anders wordt een waarschuwingsvenster voor "ongeldig bestand" weergegeven. De titel van het bestand dat momenteel wordt bewerkt, wordt ook gewijzigd in de nieuwe locatie die door de gebruiker is opgegeven.

def save_current_file(zelf):
zo niet zelf.bestandspad:
new_file_path, filter_type = QFileDialog.getSaveFileName(self, "Sla dit bestand op"
als… ", "", "Alle bestanden (*)")
indien nieuw_bestandspad:
zelf.file_path = nieuw_file_path
anders:
zelf.invalid_path_alert_message()
retourneer False
file_contents = zelf.scrollable_text_area.naarPlainText()
met open(zelf).file_path, "w") als f:
f.schrijven(file_contents)
zelf.titel.setText(zelf).bestandspad)

De "closeEvent"-methode maakt deel uit van de PyQt5-API voor gebeurtenisafhandeling. Deze methode wordt aangeroepen wanneer een gebruiker een venster probeert te sluiten met de kruisknop of door op by te drukken toetsencombinatie. Bij het activeren van de close-gebeurtenis krijgt de gebruiker een dialoogvenster te zien met drie keuzes: "Ja", "Nee" en "Annuleren". De knop "Ja" slaat het bestand op en sluit de toepassing terwijl de knop "Nee" het bestand sluit zonder de inhoud op te slaan. De knop "Annuleren" sluit het dialoogvenster en brengt de gebruiker terug naar de toepassing.

def closeEvent(zelf, evenement):
messageBox = QMessageBox()
title = "Applicatie afsluiten?"
message = "WAARSCHUWING !!\n\nAls u afsluit zonder op te slaan, zullen eventuele wijzigingen in het bestand file
verdwaald zijn.\n\nBestand opslaan voordat u afsluit?"
reply = messageBox.vraag (zelf, titel, bericht, messageBox).Ja | berichten box.Nee |
berichten box.Annuleren, messageBox.Annuleren)
if reply == messageBox.Ja:
return_value = zelf.save_current_file()
if return_value == Onwaar:
evenement.negeren()
elif reply == messageBox.Nee:
evenement.aanvaarden()
anders:
evenement.negeren()

Het waarschuwingsvenster "ongeldig bestand" heeft geen toeters en bellen. Het geeft alleen de boodschap weer dat het bestandspad niet kon worden bepaald.

def invalid_path_alert_message(self):
messageBox = QMessageBox()
berichten box.setWindowTitle("Ongeldig bestand")
berichten box.setText("Geselecteerde bestandsnaam of pad is niet geldig. Selecteer een geldig bestand.")
berichten box.exec()

Ten slotte wordt de hoofdtoepassingslus voor het afhandelen van gebeurtenissen en het tekenen van widgets gestart met behulp van de ".exec_()” methode.

if __name__ == '__main__':
app = QApplicatie(sys.argv)
w = Venster()
met wie.toon gemaximaliseerd()
sys.afsluiten (app.exec_())

De app uitvoeren

Sla gewoon de volledige code op in een tekstbestand, stel de bestandsextensie in op ".py", markeer het uitvoerbare bestand en voer het uit om de app te starten. Als de bestandsnaam bijvoorbeeld "simple_text_editor" is.py", moet u de volgende twee opdrachten uitvoeren:

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

Dingen die u kunt doen om de code te verbeteren

De hierboven uitgelegde code werkt prima voor een kale teksteditor. Het is echter misschien niet handig voor praktische doeleinden, omdat het veel functies mist die vaak worden gezien in goede teksteditors. U kunt de code verbeteren door nieuwe functies toe te voegen, zoals regelnummers, regelmarkering, syntaxisaccentuering, meerdere tabbladen, sessiebesparing, werkbalk, vervolgkeuzemenu's, detectie van bufferwijzigingen, enz.

Conclusie

Dit artikel richt zich voornamelijk op het bieden van een startpunt voor het maken van PyQt-apps. Als je fouten in de code vindt of iets wilt voorstellen, feedback is welkom.

Hoe de muisaanwijzer en cursorgrootte, kleur en schema op Windows 10 te veranderen
De muisaanwijzer en cursor in Windows 10 zijn zeer belangrijke aspecten van het besturingssysteem. Dit geldt ook voor andere besturingssystemen, dus i...
Gratis en open source game-engines voor het ontwikkelen van Linux-games
Dit artikel behandelt een lijst met gratis en open source game-engines die kunnen worden gebruikt voor het ontwikkelen van 2D- en 3D-games op Linux. E...
Shadow of the Tomb Raider voor Linux-zelfstudie
Shadow of the Tomb Raider is de twaalfde toevoeging aan de Tomb Raider-serie - een actie-avonturengame-franchise gemaakt door Eidos Montreal. De game ...