[PYTHON] Erstellen Sie eine GUI auf dem Terminal mit Flüchen

Was ist Flüche?

Laut dem offiziellen Dokument

Die curses-Bibliothek bietet terminalunabhängige Bildschirmzeichnung und Tastaturverarbeitung für textbasierte Terminals (Terminals) wie VT100s, Linux-Konsolen und Emulationsterminals, die von verschiedenen Programmen bereitgestellt werden. Das Terminal unterstützt verschiedene Steuercodes zum Ausführen allgemeiner Vorgänge wie Bewegen des Cursors, Scrollen des Bildschirms und Löschen des Bereichs. Verschiedene Arten von Terminals können sehr unterschiedliche Steuercodes verwenden und haben oft eine besondere Angewohnheit.

Dies kann nützlich sein, wenn Sie eine einfache GUI erstellen oder mit Daten auf einem Server arbeiten möchten, auf den nur mit ssh zugegriffen werden kann. Sie können auch den Inhalt von CSV und DB anzeigen.

Was du machen willst

Angenommen, Sie haben die folgende CSV-Datei.

ID Prefecture Capital Population Area Density
1 Aichi Nagoya 70,43,235 5,153.81 1,366
2 Akita Akita 11,89,215 11,612.11 102
3 Aomori Aomori 14,75,635 9,606.26 154
... ... ... ... ... ...
45 Yamagata Yamagata 12,44,040 9,323.34 133
46 Yamaguchi Yamaguchi 15,28,107 6,110.76 250
47 Yamanashi Kofu 8,88,170 4,465.37 199

Ich möchte eine GUI erstellen, die den Inhalt des Terminals anzeigen und die zu verarbeitende Präfektur auswählen kann.

Implementierung

main.py


# -*- coding: utf-8 -*-
import curses
import csv
from math import ceil

ROWS_PER_PAGE = 20

ENTER = ord( "\n" )
ESC = 27
DOWN = curses.KEY_DOWN
UP = curses.KEY_UP

class UI():

    def __init__(self, header, rows):
        super().__init__()
        self.header = header 
        self.rows = rows
        #Initialisieren
        self.screen = curses.initscr()
        curses.noecho()
        curses.cbreak()
        curses.start_color()
        self.screen.keypad(1)
        #Farbeinstellungen
        curses.init_pair(1, curses.COLOR_BLACK, curses.COLOR_CYAN)
        self.highlight_text = curses.color_pair(1) #Verwenden Sie die Paar-ID in der obigen Zeile
        self.normal_text = curses.A_NORMAL
        self.screen.border(0)
        curses.curs_set(0)
        self.rows_per_page = ROWS_PER_PAGE
        self.total_rows = len(self.rows)
        #Notieren Sie die Breite jeder Spalte
        self.widths = []
        #Randzeichnung
        self.tavnit = '|'
        self.separator = '+'

        for index, title in enumerate(self.header):
            #Machen Sie den Spaltentitel und den längsten Wert jeder Zeile zur Breite der Spalte
            max_col_length = max([len(row[index]) for row in self.rows])
            max_col_length = max(max_col_length, len(title))
            self.widths.append(max_col_length)

        #Rahmeneinstellungen
        for w in self.widths:
            #Es sieht aus wie das:
            # | %-2s | %-10s | %-10s | %-11s | %-9s | %-7s |
            self.tavnit += " %-"+"%ss |" % (w,)
            #Es sieht aus wie das:
            # +----+------------+------------+-------------+-----------+---------+
            self.separator += '-'*w + '--+'

        self.total_pages = int(ceil(self.total_rows / self.rows_per_page))
        self.position = 1
        self.page = 1
        #Nachricht angezeigt werden
        self.msg = 'Page: {}/{}'.format(self.page, self.total_pages)

    def end(self):
        curses.endwin()

    def draw(self):
        self.screen.erase()
        #Nachricht oben anzeigen
        self.screen.addstr(1, 2, self.msg, self.normal_text)
        #Rand auf dem Tisch
        self.screen.addstr(2, 2, self.separator, self.normal_text)
        #Kopfzeile anzeigen
        self.screen.addstr(3, 2, self.tavnit % tuple(self.header), self.normal_text)
        #Grenze zwischen Header und Inhalt
        self.screen.addstr(4, 2, self.separator, self.normal_text)
        #Zeichne jede Linie
        row_start = 1 + (self.rows_per_page * (self.page - 1))
        row_end = self.rows_per_page + 1 + (self.rows_per_page * (self.page - 1))
        for i in range(row_start, row_end):
            if i >= self.total_rows + 1:
                break
            row_number = i + (self.rows_per_page * (self.page - 1))
            #Linie markieren
            if (row_number == self.position + (self.rows_per_page * (self.page - 1))):
                color = self.highlight_text
            else:
                color = self.normal_text
            #Da gibt es 4 Zeilen wie Nachrichten und Rahmen oben+4
            draw_number = i - (self.rows_per_page * (self.page - 1)) + 4 #Da gibt es 4 Zeilen wie Nachrichten und Rahmen oben
            self.screen.addstr(draw_number , 2, self.tavnit % tuple(self.rows[i - 1]), color)
        #Unterer Rand der Tabelle,Da gibt es 4 Zeilen wie Nachrichten und Rahmen oben+4
        bottom = min(row_end, self.total_rows + 1) - (self.rows_per_page * (self.page - 1)) + 4
        self.screen.addstr(bottom, 2, self.separator, self.normal_text)
        self.screen.refresh()

    def down(self):
        if self.page == self.total_pages:
            if self.position < self.total_rows:
                self.position += 1
        else:
            if self.position < self.rows_per_page + (self.rows_per_page * (self.page - 1)):
                self.position += 1
            else:
                self.page += 1
                self.position = 1 + (self.rows_per_page * (self.page - 1))
                self.msg = 'Page: {}/{}'.format(self.page, self.total_pages)
        self.draw()

    def up(self):
        if self.page == 1:
            if self.position > 1:
                self.position -= 1
        else:
            if self.position > (1 + (self.rows_per_page * (self.page - 1))):
                self.position -= 1
            else:
                self.page -= 1
                self.position = self.rows_per_page + (self.rows_per_page * (self.page - 1))
                self.msg = 'Page: {}/{}'.format(self.page, self.total_pages)
        self.draw()

    def esc(self):
        self.end()

    def enter(self):
        #Was Sie hier machen wollen
        prefecture_id = self.rows[self.position - 1][0]
        prefecture = self.rows[self.position - 1][1]
        self.msg = 'Page: {}/{} ({} {} was selected.)' \
                .format(self.page, self.total_pages, prefecture_id, prefecture)
        self.draw()

    def loop(self):
        #Erkennt den eingegebenen Schlüssel
        key = self.screen.getch()
        while 1:
            if key == ENTER:
                self.enter()
            elif key == ESC:
                self.esc()
                break
            elif key == DOWN:
                self.down()
            elif key == UP:
                self.up()
            key = self.screen.getch()

if __name__ == '__main__':
    with open('prefectures.csv') as f:
        reader = csv.reader(f)
        data = list(reader)
    header = data[0]
    rows = data[1:]
    
    ui = UI(header, rows)
    ui.draw()
    ui.loop()

Lauf

$ python main.py

Ergebnis

Die maximale Anzahl von Zeilen auf der Seite beträgt 20. Sie können mit und scrollen. Wenn Sie die Eingabetaste drücken (Zurück), werden die Informationen der entsprechenden Präfektur in der Nachricht angezeigt. Beenden Sie die GUI mit "ESC".

result

Recommended Posts

Erstellen Sie eine GUI auf dem Terminal mit Flüchen
Erstellen Sie mit tkinter eine Python-GUI
Erstellen Sie mit dem Sympy-Modul ein Diagramm
[Python] Ein Fortschrittsbalken auf dem Terminal
So schreiben Sie eine GUI mit dem Befehl maya
[CRUD] [Django] Erstellen Sie eine CRUD-Site mit dem Python-Framework Django ~ 1 ~
Erstellen Sie unter Linux einen QR-Code für die URL
[CRUD] [Django] Erstellen Sie eine CRUD-Site mit dem Python-Framework Django ~ 2 ~
[CRUD] [Django] Erstellen Sie eine CRUD-Site mit dem Python-Framework Django ~ 3 ~
[CRUD] [Django] Erstellen Sie eine CRUD-Site mit dem Python-Framework Django ~ 4 ~
[CRUD] [Django] Erstellen Sie eine CRUD-Site mit dem Python-Framework Django ~ 5 ~
Durchsuchen Sie die Tabelle mit sqlalchemy und erstellen Sie ein Wörterbuch
Erstellen Sie ein Klassenzimmer auf Jupyterhub
Erstellen Sie eine neue CSV mit Pandas basierend auf der lokalen CSV
Erstellen Sie mithilfe der Twitter-Streaming-API einen Echtzeit-Bot für die automatische Antwort
Ich habe ein VGG16-Modell mit TensorFlow gemacht (unterwegs)
Erstellen Sie eine Python-Umgebung auf dem Mac (2017/4)
Erstellen Sie ein verschachteltes Wörterbuch mit defaultdict
Erstellen Sie einen SlackBot-Dienst für Pepper
Erstellen Sie eine Linux-Umgebung unter Windows 10
Erstellen Sie eine Python-Umgebung in Centos
Verwenden einer seriellen Konsole unter Ubuntu 20.04
Hinweise zur Verwendung von matplotlib auf dem Server
Erstellen Sie mit Boost.Python einen C-Sprach-Wrapper
Steuern Sie den Motor mit einem Motortreiber mit Python auf Raspberry Pi 3!
Verwenden Sie sqlalchemy, um die DB-Tabelle zu durchsuchen und eine Datenflamme für Pandas zu erstellen
[Ev3dev] Erstellen Sie ein Programm, das das LCD (Bildschirm) mit Python erfasst
Erstellen Sie Verknüpfungen, um Python-Dateien auf dem Terminal mit VScode auszuführen
Erstellen Sie eine Python-Umgebung auf Ihrem Mac
Erstellen Sie eine GUI-App mit Tkinter of Python
Erstellen Sie eine Anwendung mit der Spotify-API
Schätzen Sie die Wahrscheinlichkeit, dass eine Münze mit MCMC erscheint
Erstellen Sie mit dem Python-Anforderungsmodul einen Datensatz mit Anhängen in KINTONE
Erstellen Sie eine virtuelle Linux-Maschine unter Windows
Erstellen Sie mit Pandas einen Datenrahmen aus Excel
Fügen Sie mithilfe des Keras-Backends eine Ebene hinzu
[19.11.2015] So registrieren Sie einen Dienst lokal mit dem Python SDK bei naoqi os
So erstellen Sie mit Elasticsearch unter macOS Sierra schnell eine morphologische Analyseumgebung
Versuchen Sie, die Umweltkonzentration organischer Fluorverbindungen mit offenen Daten auf einer Karte darzustellen
Erstellen Sie eine REST-API mit dem in Lobe und TensorFlow Serving erlernten Modell.
Verwendung des digitalen 1-Draht-Temperatursensors DS18B20 mit Raspberry Pi von Python
[AWS Lambda] Erstellen Sie ein Bereitstellungspaket mit dem Amazon Linux Docker-Image
Eine süchtig machende Geschichte bei der Verwendung von Tensorflow unter Android
Erstellen Sie eine GIF-Datei mit Pillow in Python
Erstellen Sie eine mit tkinter erstellte ausführbare GUI-Datei
Versuchen Sie, QR-Code mit Raspberry Pi zu verwenden
Hinweise zum Anpassen der Diktatlistenklasse
Erstellen wir eine REST-API mit SpringBoot + MongoDB
Python: Versuchen Sie, die Benutzeroberfläche von Pythonista 3 auf dem iPad zu verwenden
Sie können auch mit Python problemlos eine GUI erstellen
Erstellen Sie mit ClustalW2 einen phylogenetischen Baum aus Biopyton
Erstellen Sie eine Webmap mit Python und GDAL
Syntaxhervorhebung in der Befehlszeile mithilfe von Pylements
[Venv] Erstellen Sie eine virtuelle Python-Umgebung unter Ubuntu
Versuchen Sie, einen neuen Befehl unter Linux zu erstellen
Erstellen Sie mit Jupplotlib interaktive 3D-Diagramme in Jupyter Lab
Lassen Sie den Summer mit Python auf Raspberry Pi 3 erklingen!
Erstellen Sie ein Besuchermeldungssystem mit Raspberry Pi