Pitone

Come scrivere un semplice editor di testo in PyQt5

Come scrivere un semplice editor di testo in PyQt5
Questo articolo tratterà una guida sulla creazione di un semplice editor di testo in Python3 e PyQt5. Qt5 è un insieme di librerie multipiattaforma scritte in C++, usate principalmente per creare ricche applicazioni grafiche. PyQt5 fornisce collegamenti Python per l'ultima versione di Qt5. Tutti gli esempi di codice in questo articolo sono testati con Python 3.8.2 e PyQt5 versione 5.14.1 su Ubuntu 20.04.

Installazione di PyQt5 in Linux

Per installare PyQt5 nell'ultima versione di Ubuntu, esegui il comando seguente:

$ sudo apt install python3-pyqt5

Se stai utilizzando un'altra distribuzione Linux, cerca il termine "Pyqt5" ​​nel gestore pacchetti e installalo da lì. In alternativa, puoi installare PyQt5 dal gestore di pacchetti pip usando il comando seguente:

$ pip installa pyqt5

Nota che in alcune distribuzioni potresti dover usare il comando pip3 per installare correttamente PyQt5.

Codice completo

Sto postando il codice completo in anticipo in modo che tu possa capire meglio il contesto per i singoli frammenti di codice spiegato più avanti nell'articolo. Se hai familiarità con Python e PyQt5, puoi semplicemente fare riferimento al codice qui sotto e saltare la spiegazione.

#!/usr/bin/env python3
sistema di importazione
da PyQt5.Importazione QtWidget QWidget, QApplication, QVBoxLayout, QHBoxLayout
da PyQt5.Importazione QtWidgets QTextEdit, QLabel, QShortcut, QFileDialog, QMessageBox
da PyQt5.Importazione QtGui QKeySequence
da PyQt5 importa Qt
classe Finestra (QWidget):
def __init__(self):
super().__dentro__()
se stesso.file_path = Nessuno
se stesso.open_new_file_shortcut = QShortcut(QKeySequence('Ctrl+O'), self)
se stesso.open_new_file_shortcut.attivato.connettersi (auto).apri_nuovo_file)
se stesso.save_current_file_shortcut = QShortcut(QKeySequence('Ctrl+S'), self)
se stesso.save_current_file_shortcut.attivato.connettersi (auto).save_current_file)
vbox = QVBoxLayout()
text = "File senza titolo"
se stesso.titolo = QLabel (testo)
se stesso.titolo.setWordWrap(Vero)
se stesso.titolo.setAlignment(Qt.Qt.Allinea al centro)
vbox.addWidget(self.titolo)
se stesso.setLayout(vbox)
se stesso.scrollable_text_area = QTextEdit()
vbox.addWidget(self.area_testo_scorribile)
def open_new_file(self):
se stesso.file_path, filter_type = QFileDialog.getOpenFileName(self, "Apri nuovo file",
"", "Tutti i files (*)")
se stesso.percorso del file:
con aperto (auto.percorso_file, "r") come f:
file_contents = f.leggere()
se stesso.titolo.setText(self.percorso del file)
se stesso.area_testo_scorribile.setText(file_contents)
altro:
se stesso.invalid_path_alert_message()
def save_current_file(self):
se non me stesso.percorso del file:
new_file_path, filter_type = QFileDialog.getSaveFileName(self, "Salva questo file
come… ", "", "Tutti i file (*)")
if nuovo_percorso_file:
se stesso.file_path = nuovo_file_path
altro:
se stesso.invalid_path_alert_message()
ritorno Falso
file_contents = self.area_testo_scorribile.a PlainText()
con aperto (auto.percorso_file, "w") come f:
f.write(file_contents)
se stesso.titolo.setText(self.percorso del file)
def closeEvent(self, evento):
messageBox = QMessageBox()
title = "Esci dall'applicazione?"
messaggio = "ATTENZIONE !!\n\nSe esci senza salvare, tutte le modifiche apportate al file
saranno persi.\n\nSalva il file prima di uscire?"
rispondi = messageBox.question(self, title, message, messageBox.Sì | casella dei messaggi.No |
casella dei messaggi.Annulla, messageBox.Annulla)
se rispondi == messageBox.Sì:
valore_ritorno = auto.save_current_file()
se valore_ritorno == Falso:
evento.ignorare()
elif reply == messageBox.No:
evento.accettare()
altro:
evento.ignorare()
def invalid_path_alert_message(self):
messageBox = QMessageBox()
casella dei messaggi.setWindowTitle("File non valido")
casella dei messaggi.setText("Il nome o il percorso del file selezionato nonèvalido. Si prega di selezionare un
file valido.")
casella dei messaggi.exec()
if __name__ == '__main__':
app = QApplication(sys.argomento)
w = Finestra()
w.mostraMassimizzato()
sistema.uscita (app.exec_())

Spiegazione

La prima parte del codice importa solo i moduli che verranno utilizzati nell'esempio:

sistema di importazione
da PyQt5.Importazione QtWidget QWidget, QApplication, QVBoxLayout, QHBoxLayout
da PyQt5.Importazione QtWidgets QTextEdit, QLabel, QShortcut, QFileDialog, QMessageBox
da PyQt5.Importazione QtGui QKeySequence
da PyQt5 importa Qt

Nella parte successiva viene creata una nuova classe chiamata “Window” che eredita dalla classe “QWidget”. La classe QWidget fornisce componenti grafici comunemente usati in Qt. Usando "super" puoi assicurarti che l'oggetto Qt genitore venga restituito.

classe Finestra (QWidget):
def __init__(self):
super().__dentro__()

Alcune variabili sono definite nella parte successiva. Il percorso del file è impostato su "Nessuno" per impostazione predefinita e le scorciatoie per l'apertura di un file utilizzando e salvare un file usando sono definiti usando la classe QShortcut. Queste scorciatoie sono quindi collegate ai rispettivi metodi che vengono chiamati ogni volta che un utente preme le combinazioni di tasti definite.

se stesso.file_path = Nessuno
se stesso.open_new_file_shortcut = QShortcut(QKeySequence('Ctrl+O'), self)
se stesso.open_new_file_shortcut.attivato.connettersi (auto).apri_nuovo_file)
se stesso.save_current_file_shortcut = QShortcut(QKeySequence('Ctrl+S'), self)
se stesso.save_current_file_shortcut.attivato.connettersi (auto).save_current_file)

Utilizzando la classe QVBoxLayout, viene creato un nuovo layout a cui verranno aggiunti i widget figlio child. Un'etichetta allineata al centro è impostata per il nome file predefinito usando la classe QLabel.

vbox = QVBoxLayout()
text = "File senza titolo"
se stesso.titolo = QLabel (testo)
se stesso.titolo.setWordWrap(Vero)
se stesso.titolo.setAlignment(Qt.Qt.Allinea al centro)
vbox.addWidget(self.titolo)
se stesso.setLayout(vbox)

Successivamente, viene aggiunta un'area di testo al layout utilizzando un oggetto QTextEdit. Il widget QTextEdit ti darà un'area modificabile e scorrevole con cui lavorare. Questo widget supporta copia, incolla, taglia, annulla, ripeti, seleziona tutto, ecc. tasti rapidi. Puoi anche utilizzare un menu contestuale del tasto destro all'interno dell'area di testo.

se stesso.scrollable_text_area = QTextEdit()
vbox.addWidget(self.area_testo_scorribile)

Il metodo "open_new_fie" viene chiamato quando un utente completa scorciatoia da tastiera. La classe QFileDialog presenta all'utente una finestra di dialogo per la selezione dei file. Il percorso del file viene determinato dopo che un utente seleziona un file dal selettore. Se il percorso del file è valido, il contenuto del testo viene letto dal file e impostato sul widget QTextEdit. Questo rende il testo visibile all'utente, cambia il titolo con il nuovo nome del file e completa il processo di apertura di un nuovo file. Se per qualche motivo non è possibile determinare il percorso del file, all'utente viene mostrata una finestra di avviso "file non valido".

def open_new_file(self):
se stesso.file_path, filter_type = QFileDialog.getOpenFileName(self, "Apri nuovo file", "",
"Tutti i files (*)")
se stesso.percorso del file:
con aperto (auto.percorso_file, "r") come f:
file_contents = f.leggere()
se stesso.titolo.setText(self.percorso del file)
se stesso.area_testo_scorribile.setText(file_contents)
altro:
se stesso.invalid_path_alert_message()

Il metodo "save_current_file" viene chiamato ogni volta che un utente completa scorciatoia da tastiera. Invece di recuperare un nuovo percorso file, QFileDialog ora chiede all'utente di fornire un percorso. Se il percorso del file è valido, i contenuti visibili nel widget QTextEdit vengono scritti nel percorso completo del file, altrimenti viene mostrata una casella di avviso "file non valido". Anche il titolo del file attualmente in fase di modifica viene modificato nella nuova posizione fornita dall'utente.

def save_current_file(self):
se non me stesso.percorso del file:
new_file_path, filter_type = QFileDialog.getSaveFileName(self, "Salva questo file
come… ", "", "Tutti i file (*)")
if nuovo_percorso_file:
se stesso.file_path = nuovo_file_path
altro:
se stesso.invalid_path_alert_message()
ritorno Falso
file_contents = self.area_testo_scorribile.a PlainText()
con aperto (auto.percorso_file, "w") come f:
f.write(file_contents)
se stesso.titolo.setText(self.percorso del file)

Il metodo "closeEvent" fa parte dell'API di gestione degli eventi PyQt5. Questo metodo viene chiamato ogni volta che un utente tenta di chiudere una finestra utilizzando il pulsante a croce o premendo combinazione di tasti. All'attivazione dell'evento di chiusura, all'utente viene mostrata una finestra di dialogo con tre scelte: “Sì”, “No” e “Annulla”. Il pulsante "Sì" salva il file e chiude l'applicazione mentre il pulsante "No" chiude il file senza salvare il contenuto. Il pulsante "Annulla" chiude la finestra di dialogo e riporta l'utente all'applicazione.

def closeEvent(self, evento):
messageBox = QMessageBox()
title = "Esci dall'applicazione?"
messaggio = "ATTENZIONE !!\n\nSe esci senza salvare, tutte le modifiche apportate al file verranno
essere perso.\n\nSalva il file prima di uscire?"
rispondi = messageBox.question(self, title, message, messageBox.Sì | casella dei messaggi.No |
casella dei messaggi.Annulla, messageBox.Annulla)
se rispondi == messageBox.Sì:
valore_ritorno = auto.save_current_file()
se valore_ritorno == Falso:
evento.ignorare()
elif reply == messageBox.No:
evento.accettare()
altro:
evento.ignorare()

La casella di avviso "file non valido" non ha campanelli e fischietti. Trasmette solo il messaggio che il percorso del file non può essere determinato.

def invalid_path_alert_message(self):
messageBox = QMessageBox()
casella dei messaggi.setWindowTitle("File non valido")
casella dei messaggi.setText("Il nome o il percorso del file selezionato nonèvalido. Seleziona un file valido.")
casella dei messaggi.exec()

Infine, il ciclo dell'applicazione principale per la gestione degli eventi e il disegno dei widget viene avviato utilizzando il ".exec_()” metodo.

if __name__ == '__main__':
app = QApplication(sys.argomento)
w = Finestra()
w.mostraMassimizzato()
sistema.uscita (app.exec_())

Esecuzione dell'app

Basta salvare il codice completo in un file di testo, impostare l'estensione del file su ".py", contrassegna il file eseguibile ed eseguilo per avviare l'app. Ad esempio, se il nome del file è "simple_text_editor.py", è necessario eseguire i seguenti due comandi:

$ chmod +x editor_testo_semplice.pi
$ ./editor_di_testo_semplice.pi

Cose che puoi fare per migliorare il codice

Il codice spiegato sopra funziona bene per un editor di testo essenziale. Tuttavia, potrebbe non essere utile per scopi pratici poiché manca di molte funzionalità comunemente viste in buoni editor di testo. Puoi migliorare il codice aggiungendo nuove funzionalità come numeri di riga, evidenziazione della riga, evidenziazione della sintassi, più schede, salvataggio della sessione, barra degli strumenti, menu a discesa, rilevamento della modifica del buffer ecc.

Conclusione

Questo articolo si concentra principalmente sul fornire un punto di partenza per la creazione di app PyQt. Se trovi errori nel codice o vuoi suggerire qualcosa, il feedback è benvenuto.

SuperTuxKart per Linux
SuperTuxKart è un fantastico titolo progettato per offrirti l'esperienza di Mario Kart gratuitamente sul tuo sistema Linux. È piuttosto impegnativo e ...
Tutorial Battaglia per Wesnoth
The Battle for Wesnoth è uno dei giochi di strategia open source più popolari a cui puoi giocare in questo momento. Non solo questo gioco è in svilupp...
0 A.D. Tutorial
Tra i tanti giochi di strategia in circolazione, 0 A.D. riesce a distinguersi come un titolo completo e un gioco molto profondo e tattico nonostante s...