Pyton

Jak napisać prosty edytor tekstu w PyQt5?

Jak napisać prosty edytor tekstu w PyQt5?
Ten artykuł zawiera przewodnik po tworzeniu prostego edytora tekstu w Python3 i PyQt5. Qt5 to zestaw wieloplatformowych bibliotek napisanych w C++, służących głównie do tworzenia bogatych aplikacji graficznych. PyQt5 zapewnia powiązania Pythona dla najnowszej wersji Qt5. Wszystkie próbki kodu w tym artykule są testowane w Pythonie 3.8.2 i PyQt5 wersja 5.14.1 na Ubuntu 20.04.

Instalowanie PyQt5 w Linuksie

Aby zainstalować PyQt5 w najnowszej wersji Ubuntu, uruchom poniższe polecenie:

$ sudo apt zainstaluj python3-pyqt5

Jeśli używasz innej dystrybucji Linuksa, wyszukaj termin „Pyqt5” w menedżerze pakietów i zainstaluj go stamtąd. Alternatywnie możesz zainstalować PyQt5 z menedżera pakietów pip za pomocą poniższego polecenia:

$ pip zainstaluj pyqt5

Zauważ, że w niektórych dystrybucjach może być konieczne użycie polecenia pip3, aby poprawnie zainstalować PyQt5.

Pełny kod

Wcześniej publikuję pełny kod, aby lepiej zrozumieć kontekst poszczególnych fragmentów kodu wyjaśnionych w dalszej części artykułu. Jeśli znasz Pythona i PyQt5, możesz po prostu zapoznać się z poniższym kodem i pominąć wyjaśnienie.

#!/usr/bin/env python3
system importu
z PyQt5.QtWidgets importuje QWidget, QApplication, QVBoxLayout, QHBoxLayout
z PyQt5.QtWidgets importuje QTextEdit, QLabel, QShortcut, QFileDialog, QMessageBox
z PyQt5.Import QtGui QKeySequence
z PyQt5 importuj Qt
okno klasy (QWidget):
def __init__(self):
Wspaniały().__w tym__()
samego siebie.ścieżka_pliku = Brak
samego siebie.open_new_file_shortcut = QShortcut(QKeySequence('Ctrl+O'), self)
samego siebie.open_new_file_shortcut.aktywowany.połącz (siebie.otwórz_nowy_plik)
samego siebie.save_current_file_shortcut = QShortcut(QKeySequence('Ctrl+S'), self)
samego siebie.save_current_file_shortcut.aktywowany.połącz (siebie.zapisz_bieżący_plik)
vbox = QVBoxUkład()
text = "Plik bez tytułu"
samego siebie.tytuł = Etykieta Q(tekst)
samego siebie.tytuł.ustawWordWrap(prawda)
samego siebie.tytuł.ustaw wyrównanie(Qt.Qt.Wyrównaj do środka)
vbox.addWidget(self.tytuł)
samego siebie.setLayout(vbox)
samego siebie.scrollable_text_area = QTextEdit()
vbox.addWidget(self.scrollable_text_area)
def open_new_file(self):
samego siebie.ścieżka_pliku, typ_filtra = QFileDialog.getOpenFileName(self, "Otwórz nowy plik",
"", "Wszystkie pliki (*)")
jeśli ja.ścieżka pliku:
z otwartym (własnym.file_path, "r") jako f:
zawartość_pliku = f.czytać()
samego siebie.tytuł.setText(self.ścieżka pliku)
samego siebie.scrollable_text_area.setText(file_contents)
jeszcze:
samego siebie.invalid_path_alert_message()
def save_current_file(self):
jeśli nie ja.ścieżka pliku:
new_file_path, filter_type = QFileDialog.getSaveFileName(self, "Zapisz ten plik
jako… ", "", "Wszystkie pliki (*)")
jeśli new_file_path:
samego siebie.ścieżka_pliku = nowa_ścieżka_pliku
jeszcze:
samego siebie.invalid_path_alert_message()
powrót Fałsz
zawartość_pliku = self.scrollable_text_area.doZwykłyTekst()
z otwartym (własnym.file_path, "w") jako f:
fa.zapis(zawartość_pliku)
samego siebie.tytuł.setText(self.ścieżka pliku)
def closeEvent(self, event):
MessageBox = QMessageBox()
title = „Zamknij aplikację?"
komunikat = „OSTRZEŻENIE !!\n\nJeśli zakończysz bez zapisywania, wszelkie zmiany wprowadzone w pliku
będzie zgubiony.\n\nZapisz plik przed zakończeniem?"
odpowiedź = skrzynka wiadomości.pytanie (self, tytuł, wiadomość, messageBox).Tak | skrzynka pocztowa.Nie |
skrzynka pocztowa.Anuluj, skrzynka wiadomości.Anuluj)
jeśli odpowiedź == skrzynka wiadomości.Tak:
zwracana_wartość = siebie.zapisz_bieżący_plik()
if return_value == False:
zdarzenie.ignorować()
elif odpowiedź == skrzynka wiadomości.Nie:
zdarzenie.zaakceptować()
jeszcze:
zdarzenie.ignorować()
def invalid_path_alert_message(self):
MessageBox = QMessageBox()
skrzynka pocztowa.setWindowTitle("Nieprawidłowy plik")
skrzynka pocztowa.setText("Wybrana nazwa pliku lub ścieżka jest nieprawidłowa. Proszę wybrać
prawidłowy plik.")
skrzynka pocztowa.exec()
if __name__ == '__main__':
aplikacja = QAplikacja (sys.argv)
w = okno()
w.pokażMaksymalizację()
system.wyjdź (aplikacja.exec_())

Wyjaśnienie

Pierwsza część kodu po prostu importuje moduły, które będą używane w całym przykładzie:

system importu
z PyQt5.QtWidgets importuje QWidget, QApplication, QVBoxLayout, QHBoxLayout
z PyQt5.QtWidgets importuje QTextEdit, QLabel, QShortcut, QFileDialog, QMessageBox
z PyQt5.Import QtGui QKeySequence
z PyQt5 importuj Qt

W następnej części tworzona jest nowa klasa o nazwie „Window”, która dziedziczy po klasie „QWidget”. Klasa QWidget dostarcza powszechnie używane komponenty graficzne w Qt. Używając „super” możesz upewnić się, że zwrócony zostanie nadrzędny obiekt Qt.

okno klasy (QWidget):
def __init__(self):
Wspaniały().__w tym__()

Niektóre zmienne są zdefiniowane w następnej części. Ścieżka pliku jest domyślnie ustawiona na „Brak”, a skróty do otwierania pliku za pomocą i zapisanie pliku za pomocą są definiowane za pomocą klasy QShortcut. Skróty te są następnie łączone z odpowiednimi metodami, które są wywoływane za każdym razem, gdy użytkownik naciśnie zdefiniowaną kombinację klawiszy.

samego siebie.ścieżka_pliku = Brak
samego siebie.open_new_file_shortcut = QShortcut(QKeySequence('Ctrl+O'), self)
samego siebie.open_new_file_shortcut.aktywowany.połącz (siebie.otwórz_nowy_plik)
samego siebie.save_current_file_shortcut = QShortcut(QKeySequence('Ctrl+S'), self)
samego siebie.save_current_file_shortcut.aktywowany.połącz (siebie.zapisz_bieżący_plik)

Za pomocą klasy QVBoxLayout tworzony jest nowy układ, do którego zostaną dodane widżety podrzędne. Etykieta wyrównana do środka jest ustawiana dla domyślnej nazwy pliku przy użyciu klasy QLabel.

vbox = QVBoxUkład()
text = "Plik bez tytułu"
samego siebie.tytuł = Etykieta Q(tekst)
samego siebie.tytuł.ustawWordWrap(prawda)
samego siebie.tytuł.ustaw wyrównanie(Qt.Qt.Wyrównaj do środka)
vbox.addWidget(self.tytuł)
samego siebie.setLayout(vbox)

Następnie do układu dodawany jest obszar tekstowy za pomocą obiektu QTextEdit. Widżet QTextEdit zapewni edytowalny, przewijalny obszar do pracy. Ten widżet obsługuje typowe kopiowanie, wklejanie, wycinanie, cofanie, ponawianie, zaznaczanie wszystkiego itp. Skróty klawiszowe. Możesz także użyć menu kontekstowego prawego przycisku myszy w obszarze tekstowym.

samego siebie.scrollable_text_area = QTextEdit()
vbox.addWidget(self.scrollable_text_area)

Metoda „open_new_fie” jest wywoływana po zakończeniu przez użytkownika skrót klawiszowy. Klasa QFileDialog przedstawia użytkownikowi okno wyboru pliku. Ścieżka pliku jest określana po wybraniu przez użytkownika pliku z selektora. Jeśli ścieżka pliku jest prawidłowa, zawartość tekstowa jest odczytywana z pliku i ustawiana na widżet QTextEdit. Dzięki temu tekst jest widoczny dla użytkownika, zmienia tytuł na nową nazwę pliku i kończy proces otwierania nowego pliku. Jeśli z jakiegoś powodu nie można określić ścieżki do pliku, użytkownikowi zostanie wyświetlone okno z ostrzeżeniem „nieprawidłowy plik”.

def open_new_file(self):
samego siebie.ścieżka_pliku, typ_filtra = QFileDialog.getOpenFileName(self, "Otwórz nowy plik", "",
"Wszystkie pliki (*)")
jeśli ja.ścieżka pliku:
z otwartym (własnym.file_path, "r") jako f:
zawartość_pliku = f.czytać()
samego siebie.tytuł.setText(self.ścieżka pliku)
samego siebie.scrollable_text_area.setText(file_contents)
jeszcze:
samego siebie.invalid_path_alert_message()

Metoda „zapisz_bieżący_plik” jest wywoływana za każdym razem, gdy użytkownik kończy skrót klawiszowy. Zamiast pobierać nową ścieżkę do pliku, QFileDialog prosi teraz użytkownika o podanie ścieżki. Jeśli ścieżka pliku jest poprawna, zawartość widoczna w widżecie QTextEdit jest zapisywana do pełnej ścieżki pliku, w przeciwnym razie wyświetlane jest okno ostrzeżenia o nieprawidłowym pliku. Tytuł aktualnie edytowanego pliku jest również zmieniany na nową lokalizację podaną przez użytkownika.

def save_current_file(self):
jeśli nie ja.ścieżka pliku:
new_file_path, filter_type = QFileDialog.getSaveFileName(self, "Zapisz ten plik
jako… ", "", "Wszystkie pliki (*)")
jeśli new_file_path:
samego siebie.ścieżka_pliku = nowa_ścieżka_pliku
jeszcze:
samego siebie.invalid_path_alert_message()
powrót Fałsz
zawartość_pliku = self.scrollable_text_area.doZwykłyTekst()
z otwartym (własnym.file_path, "w") jako f:
fa.zapis(zawartość_pliku)
samego siebie.tytuł.setText(self.ścieżka pliku)

Metoda „closeEvent” jest częścią API obsługi zdarzeń PyQt5. Ta metoda jest wywoływana za każdym razem, gdy użytkownik próbuje zamknąć okno za pomocą przycisku krzyżyka lub naciskając kombinacja klawiszy. Po uruchomieniu zdarzenia zamknięcia, użytkownikowi wyświetlane jest okno dialogowe z trzema opcjami: „Tak”, „Nie” i „Anuluj”. Przycisk „Tak” zapisuje plik i zamyka aplikację, a przycisk „Nie” zamyka plik bez zapisywania zawartości. Przycisk „Anuluj” zamyka okno dialogowe i przenosi użytkownika z powrotem do aplikacji.

def closeEvent(self, event):
MessageBox = QMessageBox()
title = „Zamknij aplikację?"
komunikat = „OSTRZEŻENIE !!\n\nJeśli zakończysz bez zapisywania, wszelkie zmiany wprowadzone w pliku zostaną
być zgubionym.\n\nZapisz plik przed zakończeniem?"
odpowiedź = skrzynka wiadomości.pytanie (self, tytuł, wiadomość, messageBox).Tak | skrzynka pocztowa.Nie |
skrzynka pocztowa.Anuluj, skrzynka wiadomości.Anuluj)
jeśli odpowiedź == skrzynka wiadomości.Tak:
zwracana_wartość = siebie.zapisz_bieżący_plik()
if return_value == False:
zdarzenie.ignorować()
elif odpowiedź == skrzynka wiadomości.Nie:
zdarzenie.zaakceptować()
jeszcze:
zdarzenie.ignorować()

W okienku alertu „nieprawidłowy plik” nie ma żadnych dzwonków i gwizdków. Po prostu przekazuje wiadomość, że nie można określić ścieżki do pliku.

def invalid_path_alert_message(self):
MessageBox = QMessageBox()
skrzynka pocztowa.setWindowTitle("Nieprawidłowy plik")
skrzynka pocztowa.setText("Wybrana nazwa pliku lub ścieżka jest nieprawidłowa. Proszę wybrać poprawny plik.")
skrzynka pocztowa.exec()

Na koniec główna pętla aplikacji do obsługi zdarzeń i rysowania widżetów jest uruchamiana za pomocą „.exec_()” metoda.

if __name__ == '__main__':
aplikacja = QAplikacja (sys.argv)
w = okno()
w.pokażMaksymalizację()
system.wyjdź (aplikacja.exec_())

Uruchamianie aplikacji

Po prostu zapisz pełny kod do pliku tekstowego, ustaw rozszerzenie pliku na „.py”, zaznacz plik wykonywalny i uruchom go, aby uruchomić aplikację. Na przykład, jeśli nazwa pliku to „prosty_edytor_tekstu.py”, musisz uruchomić następujące dwie komendy:

$ chmod +x prosty_edytor_tekstu.py
$ ./prosty_edytor_tekstu.py

Co możesz zrobić, aby ulepszyć kodeks

Wyjaśniony powyżej kod działa dobrze w przypadku zwykłego edytora tekstu. Jednak może nie być przydatny do celów praktycznych, ponieważ brakuje mu wielu funkcji powszechnie spotykanych w dobrych edytorach tekstu. Możesz ulepszyć kod, dodając nowe funkcje, takie jak numery linii, podświetlanie linii, podświetlanie składni, wiele kart, zapisywanie sesji, pasek narzędzi, rozwijane menu, wykrywanie zmiany bufora itp.

Wniosek

Ten artykuł koncentruje się głównie na zapewnieniu podstawy do tworzenia aplikacji PyQt. Jeśli znajdziesz błędy w kodzie lub chcesz coś zasugerować, mile widziane są opinie.

Gry 5 najlepszych gier zręcznościowych dla systemu Linux
5 najlepszych gier zręcznościowych dla systemu Linux
W dzisiejszych czasach komputery to poważne maszyny używane do gier. Jeśli nie możesz uzyskać nowego wysokiego wyniku, będziesz wiedział, o co mi chod...
Gry Bitwa o Wesnoth 1.13.6 Wydanie rozwojowe
Bitwa o Wesnoth 1.13.6 Wydanie rozwojowe
Bitwa o Wesnoth 1.13.6 wydana w zeszłym miesiącu jest szóstą wersją rozwojową w 1.13.Seria x i zapewnia szereg ulepszeń, w szczególności w interfejsie...
Gry Jak zainstalować League Of Legends na Ubuntu 14.04
Jak zainstalować League Of Legends na Ubuntu 14.04
Jeśli jesteś fanem League of Legends, to jest okazja do przetestowania League of Legends. Pamiętaj, że LOL jest obsługiwany w PlayOnLinux, jeśli jeste...