Python

So schreiben Sie einen einfachen Texteditor in PyQt5

So schreiben Sie einen einfachen Texteditor in PyQt5
Dieser Artikel behandelt eine Anleitung zum Erstellen eines einfachen Texteditors in Python3 und PyQt5. Qt5 ist ein Satz plattformübergreifender Bibliotheken, die in C++ geschrieben sind und hauptsächlich zum Erstellen umfangreicher grafischer Anwendungen verwendet werden. PyQt5 bietet Python-Bindungen für die neueste Version von Qt5. Alle Codebeispiele in diesem Artikel wurden mit Python 3 getestet.8.2 und PyQt5-Version 5.14.1 unter Ubuntu 20.04.

PyQt5 unter Linux installieren

Um PyQt5 in der neuesten Version von Ubuntu zu installieren, führen Sie den folgenden Befehl aus:

$ sudo apt install python3-pyqt5

Wenn Sie eine andere Linux-Distribution verwenden, suchen Sie im Paketmanager nach dem Begriff „Pyqt5“ und installieren Sie ihn von dort aus. Alternativ können Sie PyQt5 über den pip-Paketmanager mit dem folgenden Befehl installieren:

$ pip installieren pyqt5

Beachten Sie, dass Sie in einigen Distributionen möglicherweise den Befehl pip3 verwenden müssen, um PyQt5 korrekt zu installieren.

Vollständiger Code

Ich poste vorab den vollständigen Code, damit Sie den Kontext für einzelne Code-Snippets, die später im Artikel erläutert werden, besser verstehen können. Wenn Sie mit Python und PyQt5 vertraut sind, können Sie einfach auf den folgenden Code verweisen und die Erklärung überspringen.

#!/usr/bin/env python3
Importsystem
von PyQt5.QtWidgets importieren QWidget, QApplication, QVBoxLayout, QHBoxLayout
von PyQt5.QtWidgets importieren QTextEdit, QLabel, QShortcut, QFileDialog, QMessageBox
von PyQt5.QtGui-Import von QKeySequence
aus PyQt5 Qt importieren
Klasse Window (QWidget):
def __init__(selbst):
Super().__drin__()
selbst.file_path = Keine
selbst.open_new_file_shortcut = QShortcut(QKeySequence('Strg+O'), selbst)
selbst.open_new_file_shortcut.aktiviert.verbinden (selbst.open_new_file)
selbst.save_current_file_shortcut = QShortcut(QKeySequence('Strg+S'), selbst)
selbst.save_current_file_shortcut.aktiviert.verbinden (selbst.aktuelle_Datei speichern)
vbox = QVBoxLayout()
text = "Unbenannte Datei"
selbst.Titel = QLabel(Text)
selbst.Titel.setWordWrap(True)
selbst.Titel.SetAlignment(Qt.Qt.Im Zentrum anordnen)
vbox.addWidget(selbst.Titel)
selbst.setLayout(vbox)
selbst.scrollable_text_area = QTextEdit()
vbox.addWidget(selbst.scrollable_text_area)
def open_new_file(self):
selbst.file_path, filter_type = QFileDialog.getOpenFileName(self, "Neue Datei öffnen",
"", "Alle Dateien (*)")
wenn selbst.Dateipfad:
mit offen(selbst.file_path, "r") als f:
file_contents = f.lesen()
selbst.Titel.setText(self.Dateipfad)
selbst.scrollable_text_area.setText(file_contents)
sonst:
selbst.invalid_path_alert_message()
def save_current_file(self):
wenn nicht selbst.Dateipfad:
new_file_path, filter_type = QFileDialog.getSaveFileName(self, "Diese Datei speichern
als… ", "", "Alle Dateien (*)")
wenn neuer_Dateipfad:
selbst.file_path = neuer_file_path
sonst:
selbst.invalid_path_alert_message()
falsch zurückgeben
file_contents = selbst.scrollable_text_area.toPlainText()
mit offen(selbst.file_path, "w") als f:
f.write(file_contents)
selbst.Titel.setText(self.Dateipfad)
def closeEvent(self, event):
messageBox = QMessageBox()
title = "Anwendung beenden?"
Nachricht = "WARNUNG !!\n\nWenn Sie den Vorgang ohne Speichern beenden, werden alle Änderungen an der Datei
wird verloren sein.\n\nDatei vor dem Beenden speichern?"
Antwort = MessageBox.Frage(Selbst, Titel, Nachricht, MessageBox.Ja | Nachrichtenbox.Nein |
Nachrichtenbox.Abbrechen, MessageBox.Stornieren)
wenn antworten == messageBox.Ja:
return_value = selbst.save_current_file()
if return_value == False:
Veranstaltung.ignorieren()
elif-Antwort == messageBox.Nein:
Veranstaltung.akzeptieren()
sonst:
Veranstaltung.ignorieren()
def invalid_path_alert_message(self):
messageBox = QMessageBox()
Nachrichtenbox.setWindowTitle("Ungültige Datei")
Nachrichtenbox.setText("Der ausgewählte Dateiname oder Pfad ist ungültig. Bitte wählen Sie a
gültige Datei.")
Nachrichtenbox.exec()
if __name__ == '__main__':
app = QApplication(sys.Argument)
w = Fenster()
w.showMaximized()
sys.beenden (App.exec_())

Erläuterung

Der erste Teil des Codes importiert nur Module, die im gesamten Beispiel verwendet werden:

Importsystem
von PyQt5.QtWidgets importieren QWidget, QApplication, QVBoxLayout, QHBoxLayout
von PyQt5.QtWidgets importieren QTextEdit, QLabel, QShortcut, QFileDialog, QMessageBox
von PyQt5.QtGui-Import von QKeySequence
aus PyQt5 Qt importieren

Im nächsten Teil wird eine neue Klasse namens „Window“ erstellt, die von der Klasse „QWidget“ erbt. Die QWidget-Klasse bietet häufig verwendete grafische Komponenten in Qt. Durch die Verwendung von „super“ können Sie sicherstellen, dass das übergeordnete Qt-Objekt zurückgegeben wird.

Klasse Window (QWidget):
def __init__(selbst):
Super().__drin__()

Einige Variablen werden im nächsten Teil definiert. Der Dateipfad ist standardmäßig auf „Keine“ eingestellt und Verknüpfungen zum Öffnen einer Datei mit und Speichern einer Datei mit werden mit der QShortcut-Klasse definiert. Diese Tastenkombinationen werden dann mit ihren jeweiligen Methoden verbunden, die aufgerufen werden, wenn ein Benutzer die definierten Tastenkombinationen drückt.

selbst.file_path = Keine
selbst.open_new_file_shortcut = QShortcut(QKeySequence('Strg+O'), selbst)
selbst.open_new_file_shortcut.aktiviert.verbinden (selbst.open_new_file)
selbst.save_current_file_shortcut = QShortcut(QKeySequence('Strg+S'), selbst)
selbst.save_current_file_shortcut.aktiviert.verbinden (selbst.aktuelle_Datei speichern)

Mit der Klasse QVBoxLayout wird ein neues Layout erstellt, dem untergeordnete Widgets hinzugefügt werden. Ein mittig ausgerichtetes Etikett wird für den Standarddateinamen mithilfe der QLabel-Klasse . festgelegt.

vbox = QVBoxLayout()
text = "Unbenannte Datei"
selbst.Titel = QLabel(Text)
selbst.Titel.setWordWrap(True)
selbst.Titel.SetAlignment(Qt.Qt.Im Zentrum anordnen)
vbox.addWidget(selbst.Titel)
selbst.setLayout(vbox)

Als nächstes wird dem Layout mit einem QTextEdit-Objekt ein Textbereich hinzugefügt. Das QTextEdit-Widget bietet Ihnen einen bearbeitbaren, scrollbaren Bereich, mit dem Sie arbeiten können. Dieses Widget unterstützt typisches Kopieren, Einfügen, Ausschneiden, Rückgängigmachen, Wiederholen, Alles auswählen usw. Tastatürkürzel. Sie können auch ein Rechtsklick-Kontextmenü innerhalb des Textbereichs verwenden.

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

Die Methode „open_new_fie“ wird aufgerufen, wenn ein Benutzer fertig ist Tastaturkürzel. Die Klasse QFileDialog präsentiert dem Benutzer einen Dateiauswahldialog. Der Dateipfad wird bestimmt, nachdem ein Benutzer eine Datei aus der Auswahl ausgewählt hat. Wenn der Dateipfad gültig ist, wird der Textinhalt aus der Datei gelesen und auf das QTextEdit-Widget gesetzt. Dies macht den Text für den Benutzer sichtbar, ändert den Titel in den neuen Dateinamen und schließt den Vorgang des Öffnens einer neuen Datei ab. Wenn der Dateipfad aus irgendeinem Grund nicht bestimmt werden kann, wird dem Benutzer ein Warnfeld „ungültige Datei“ angezeigt.

def open_new_file(self):
selbst.file_path, filter_type = QFileDialog.getOpenFileName(self, "Neue Datei öffnen", "",
"Alle Dateien (*)")
wenn selbst.Dateipfad:
mit offen(selbst.file_path, "r") als f:
file_contents = f.lesen()
selbst.Titel.setText(self.Dateipfad)
selbst.scrollable_text_area.setText(file_contents)
sonst:
selbst.invalid_path_alert_message()

Die Methode „save_current_file“ wird immer dann aufgerufen, wenn ein Benutzer fertig ist Tastaturkürzel. Anstatt einen neuen Dateipfad abzurufen, fordert QFileDialog den Benutzer jetzt auf, einen Pfad anzugeben. Wenn der Dateipfad gültig ist, werden die im QTextEdit-Widget sichtbaren Inhalte in den vollständigen Dateipfad geschrieben, andernfalls wird ein Warnfeld für eine ungültige Datei angezeigt. Der Titel der Datei, die gerade bearbeitet wird, wird ebenfalls an den vom Benutzer angegebenen neuen Speicherort geändert.

def save_current_file(self):
wenn nicht selbst.Dateipfad:
new_file_path, filter_type = QFileDialog.getSaveFileName(self, "Diese Datei speichern
als… ", "", "Alle Dateien (*)")
wenn neuer_Dateipfad:
selbst.file_path = neuer_file_path
sonst:
selbst.invalid_path_alert_message()
falsch zurückgeben
file_contents = selbst.scrollable_text_area.toPlainText()
mit offen(selbst.file_path, "w") als f:
f.write(file_contents)
selbst.Titel.setText(self.Dateipfad)

Die Methode „closeEvent“ ist Teil der PyQt5-Ereignisbehandlungs-API. Diese Methode wird immer dann aufgerufen, wenn ein Benutzer versucht, ein Fenster mit der Kreuztaste oder durch Drücken von zu schließen Tastenkombination. Beim Auslösen des Schließereignisses wird dem Benutzer ein Dialogfeld mit drei Auswahlmöglichkeiten angezeigt: „Ja“, „Nein“ und „Abbrechen“. Die Schaltfläche „Ja“ speichert die Datei und schließt die Anwendung, während die Schaltfläche „Nein“ die Datei schließt, ohne den Inhalt zu speichern. Die Schaltfläche „Abbrechen“ schließt das Dialogfeld und führt den Benutzer zurück zur Anwendung.

def closeEvent(self, event):
messageBox = QMessageBox()
title = "Anwendung beenden?"
Nachricht = "WARNUNG !!\n\nWenn Sie den Vorgang ohne Speichern beenden, werden alle Änderungen an der Datei
verloren sein.\n\nDatei vor dem Beenden speichern?"
Antwort = MessageBox.Frage(Selbst, Titel, Nachricht, MessageBox.Ja | Nachrichtenbox.Nein |
Nachrichtenbox.Abbrechen, MessageBox.Stornieren)
wenn antworten == messageBox.Ja:
return_value = selbst.save_current_file()
if return_value == False:
Veranstaltung.ignorieren()
elif-Antwort == messageBox.Nein:
Veranstaltung.akzeptieren()
sonst:
Veranstaltung.ignorieren()

Die Warnbox „ungültige Datei“ enthält keinen Schnickschnack. Es übermittelt nur die Nachricht, dass der Dateipfad nicht bestimmt werden konnte.

def invalid_path_alert_message(self):
messageBox = QMessageBox()
Nachrichtenbox.setWindowTitle("Ungültige Datei")
Nachrichtenbox.setText("Der ausgewählte Dateiname oder Pfad ist ungültig. Bitte wählen Sie eine gültige Datei aus.")
Nachrichtenbox.exec()

Schließlich wird die Hauptanwendungsschleife für die Ereignisbehandlung und das Zeichnen von Widgets mit dem „.exec_()”-Methode.

if __name__ == '__main__':
app = QApplication(sys.Argument)
w = Fenster()
w.showMaximized()
sys.beenden (App.exec_())

Ausführen der App

Speichern Sie einfach den vollständigen Code in einer Textdatei, setzen Sie die Dateierweiterung auf „.py“, markieren Sie die ausführbare Datei und führen Sie sie aus, um die App zu starten. Wenn der Dateiname beispielsweise „simple_text_editor“ lautet.py“, müssen Sie die folgenden zwei Befehle ausführen:

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

Dinge, die Sie tun können, um den Code zu verbessern

Der oben erläuterte Code funktioniert gut für einen einfachen Texteditor. Es kann jedoch für praktische Zwecke nicht nützlich sein, da ihm viele Funktionen fehlen, die normalerweise in guten Texteditoren zu finden sind. Sie können den Code verbessern, indem Sie neue Funktionen wie Zeilennummern, Zeilenhervorhebung, Syntaxhervorhebung, mehrere Registerkarten, Sitzungsspeicherung, Symbolleiste, Dropdown-Menüs, Erkennung von Pufferänderungen usw. hinzufügen.

Fazit

Dieser Artikel konzentriert sich hauptsächlich darauf, einen Ausgangspunkt für die Erstellung von PyQt-Apps zu bieten. Wenn Sie Fehler im Code finden oder etwas vorschlagen möchten, ist Feedback willkommen.

OpenTTD vs. Simutrans
Das Erstellen einer eigenen Transportsimulation kann Spaß machen, entspannend und äußerst verlockend sein. Deshalb sollten Sie so viele Spiele wie mög...
OpenTTD-Tutorial
OpenTTD ist eines der beliebtesten Wirtschaftssimulationsspiele auf dem Markt. In diesem Spiel musst du ein wunderbares Transportunternehmen aufbauen....
SuperTuxKart für Linux
SuperTuxKart ist ein großartiger Titel, der entwickelt wurde, um Ihnen das Mario Kart-Erlebnis kostenlos auf Ihrem Linux-System zu bieten. Es ist ziem...