Wenn Sie eine TODO-Anwendung (verteilt) jetzt nur mit Python erstellen möchten

Zusammenfassung dieses Artikels

Dieser Artikel handelt vom Qiita Summer Festival 2020 "Wenn Sie △△ (App) jetzt nur mit 〇〇 (Sprache) erstellen möchten" Es wird die als Thema erstellte ** TODO-Anwendung (verteilt) ** vorgestellt und deren Implementierung erläutert.

Ich verwende ** Python3 (Version 3.7) ** und habe den Vorgang unter Windows 10 bestätigt.

Der Code befindet sich auf dem GitHub unten. Fühlen Sie sich frei, es zu benutzen.

[Code] 1

Was ist eine TODO-Anwendung (verteilt)?

Aussehen

Die Anwendung ist wie folgt.

todo.png

todo.gif

Unten können Sie die TODO-Liste anzeigen.

Sie können eine Zeichenfolge aus dem Pulldown auswählen, um ein bestimmtes TODO anzuzeigen. Diese wird durch Drücken der Aktualisierungstaste angezeigt.

Wählen Sie eine TODO-Liste aus, um weitere Details in der Liste anzuzeigen.

Funktion

Es implementiert drei Hauptfunktionen.

Listet TODO-Dateien auf, die in mehreren Ordnern gespeichert sind

function_一覧表示.png

Diese Funktion sucht nach TODO-Dateien, die in mehreren angegebenen Ordnern gespeichert sind, und zeigt sie in einer Liste auf dem Bildschirm an.

Angenommen, Sie speichern eine ** TODO-Datei ** mit dem Namen .txt ** in einem Ordner mit dem Namen ** F: \ Document \ Qiita **, in dem eine nur mit ** Python erstellte Aufgaben-App veröffentlicht wird. In dieser Datei sind die Details von TODO, die Frist für die Veröffentlichung des aktuell verfassten Artikels und die Frist für die Veröffentlichung usw. angegeben.

Angenommen, im Ordner ** F: \ Document \ python \ django ** befindet sich eine weitere ** TODO-Datei **.

Das Problem in dieser Situation ist, dass die ** TODO-Dateien ** verteilt ** sind.

Natürlich können Sie einen ** TODO-Ordner ** erstellen und die ** TODO-Datei ** darin ablegen, aber da Sie die Ordnerhierarchie auf Ihre eigene Weise erstellt und organisiert haben, sind die zugehörigen Dateien beispielsweise ** TODO. Ich möchte die Datei ** in den gleichen Ordner legen. Darüber hinaus können wichtige Informationen hinzugefügt werden, z. B. das Hinzufügen der gesuchten Inhalte zur ** TODO-Datei **.

Um das obige Problem zu lösen, können ** TODO-Dateien ** verteilt werden.

Listen Sie nur TODOs auf, die in einem bestimmten Ordner gespeichert sind

function_特定のフォルダを一覧表示.png

Diese Funktion listet nur ** TODO-Dateien ** in einem bestimmten Ordner auf.

Wenn die Anzahl der ** TODO-Dateien ** zunimmt, ist es schwierig, die gewünschte ** TODO-Datei ** aus allen ** TODO-Dateien ** zu finden.

Aus diesem Grund haben wir es möglich gemacht, einen Ordner aus dem Pulldown-Menü auszuwählen, sodass nur ** TODO-Dateien ** angezeigt werden können, die in einem bestimmten Ordner gespeichert sind.

Zeigen Sie den detaillierten Inhalt der TODO-Datei an

function_詳細表示.png

Diese Funktion zeigt die Details am unteren Bildschirmrand an, wenn Sie auf die angezeigte Liste der ** TODO-Dateien ** klicken.

Die Details sind in der ** TODO-Datei ** beschrieben.

Grundsätzlich kann es ausreichen, ein bestimmtes ** TODO ** (was zu tun ist) mit dem Dateinamen zu schreiben. Ich dachte jedoch, es wäre besser, den Fortschritt und den Inhalt der Umfrage zu sehen, also habe ich sie umgesetzt.

Wie benutzt man

Laden Sie den Code von [GitHub] 1 am Anfang dieses Artikels herunter und legen Sie ihn in einem Ordner ab.

Führen Sie ** display.py ** aus, um die GUI zu starten.

python display.py

Die Konfigurationsdatei ist eine Datei mit dem Namen ** config.ini ** und wird im folgenden Format beschrieben.

[Dir_names]
#Der im Pulldown angezeigte Name=Absoluter Pfad des Ordners, der die TODO-Datei enthält
#Beispiel
qiita=F:\Document\800_IT selbstlernend\09_python\51_Qiita

[File_names]
#Der Name der Datei, die Sie in der TODO-Liste anzeigen möchten. Platzhalter(*)Sie können verwenden.
#Beispiel

#Dateien mit der Zeichenfolge todo am Anfang
todo=todo*

#Dateien mit py-Erweiterung
python=*.py

** * Bitte beachten Sie, dass die Suche einige Zeit dauern kann, wenn sich unter dem aufgelisteten Ordnernamen eine große Anzahl von Ordnern und Dateien befindet. ** ** ** ** Es ist eine extreme Geschichte, aber wenn Sie C: \ in den Ordnernamen schreiben, wird es eine beträchtliche Zeit dauern, bis die TODO-Liste angezeigt wird. ** ** **

** Der Zeichencode der TODO-Datei sollte UTF-8 sein. Der Detailbildschirm wird nicht angezeigt. ** ** **

Über die Implementierung

Nach Dateien suchen

operate_file_1.py


import os
import fnmatch
#root:Verzeichnisname
#patterns:Unterstützt Platzhalter im Unix-Shell-Stil. Dateinamenmuster
#yeild_folders:Gibt an, ob Dateien in Unterverzeichnissen gelesen werden sollen.

def all_files(root, patterns = "*", single_level=False, yeild_folders=False):
#split:";"Sie können mehrere Muster mit angeben.;Kann nicht in das Muster aufgenommen werden.
    patterns = patterns.split(";")

#os.Übergeben Sie den Verzeichnispfadnamen, den Verzeichnisnamen und den Dateinamen unter dem durch walk angegebenen Verzeichnis.
    for path, subdirs, files in os.walk(root):
        if yeild_folders:
            files.extend(subdirs)
        files.sort()
        for name in files:
            for pattern in patterns:
                #fnmatch gibt True zurück, wenn der Name mit dem Muster übereinstimmt.
                if fnmatch.fnmatch(name, pattern):
                    yield os.path.join(path, name)
                    break
        if single_level:
            break

Dies ist der im Python-Kochbuch beschriebene Code.

Python Cookbook 2nd Edition (Seite 89, 2.16 Verzeichnisbaumsuche) von Alex Martelli, Anna Martelli Ravenscroft, David Ascher, Masao Kamozawa, Hitoshi Toyama, Satoshi Yoshida, Sadaki Yoshimune usw. Übersetzt von O'Reilly Japan ISBN978- 4-87311-276-3

Wir suchen nach einer Übereinstimmung aus dem empfangenen Verzeichnisnamen und dem Dateinamen und geben das Ergebnis zurück.

todo suchen

todo.py


from operate_file_1 import all_files
import configparser


class Todo:
    def __init__(self):

        self.rule_file = configparser.ConfigParser()
        self.rule_file.read("./config.ini", "UTF-8")

        self.dir_name_keys = list(self.rule_file["Dir_names"].keys())
        self.dir_names = [self.rule_file["Dir_names"][key] for key in self.rule_file["Dir_names"].keys()]
        self.patterns = [self.rule_file["File_names"][key] for key in self.rule_file["File_names"].keys()]

    def search_file(self):
        paths = {}
        for index, dir_name in enumerate(self.dir_names):
            paths[self.dir_name_keys[index]] = list(all_files(dir_name, ";".join(self.patterns)))
        return paths

    def limit_search_file(self, dir_name_key):
        paths = {}
        paths[dir_name_key] = list(all_files(self.rule_file["Dir_names"][dir_name_key], ";".join(self.patterns)))
        return paths

    def get_dir_name_keys(self):
        return self.dir_name_keys

Dies ist eine Klasse, die die Einstellungen aus ** config.ini ** liest und die Datei mit der in ** operator_file_1.py ** beschriebenen Funktion durchsucht.

Verwenden Sie das in Python integrierte Modul ** [configparser] 2 **, um den Wert aus der Konfigurationsdatei zu lesen.

** search \ _file ** durchsucht die gesamte Suche, ** limit \ _ search \ _file ** durchsucht nur den angegebenen Ordner.

ToDo-Anzeige

display.py


import tkinter as tk
import os
import datetime
from todo import Todo
from gui_object import Frame, Label, Listbox, Text, Button, Combobox


class TodoDisplay:
    def __init__(self):
        self.root = tk.Tk()
        self.root.title("todo")

        self.todo = Todo()
        self.todo_list_box_dict = {}

        self.todo_list_frame = Frame(self.root)
        self.todo_list_frame.grid(column=0, row=1)
        self.todo_detail_frame = Frame(self.root)
        self.todo_detail_frame.grid(column=0, row=2)
        self.function_frame = Frame(self.root)
        self.function_frame.grid(column=0, row=0)

        self.listbox = Listbox(master=self.todo_list_frame, master_of_detail_text=self.todo_detail_frame)

        self.refresh_button = Button(master=self.function_frame)
        self.refresh_button.grid(column=1, row=0)
        self.refresh_button["text"] = "aktualisieren"
        self.refresh_button["command"] = self.refresh

        self.combbox = Combobox(master=self.function_frame)
        self.combbox.grid(column=0, row=0)
        self.set_value_for_combbox()

    def display_todo(self):
        todo_list_box_id = 0
        self.todo_list_box_dict = {}

        if (self.combbox.get() == "all") or (self.combbox.get() == ""):
            paths = self.todo.search_file()
        else:
            paths = self.todo.limit_search_file(self.combbox.get())

        for key in paths.keys():
            for path in paths[key]:
                create_time, update_time = self.get_timestamp_of_path(path)
                insert_statement = " ".join(["Erstellen", create_time, "aktualisieren", update_time, path.split("\\")[-1].split(".")[0]])
                self.listbox.insert(todo_list_box_id, insert_statement)
                self.todo_list_box_dict[todo_list_box_id] = path
                todo_list_box_id = todo_list_box_id + 1

        self.listbox.set_todo_list(self.todo_list_box_dict)

    def get_timestamp_of_path(self, path):
        stat_result = os.stat(path)
        create_time = datetime.datetime.fromtimestamp(stat_result.st_ctime).strftime("%Y/%m/%d %H:%M:%S")
        update_time = datetime.datetime.fromtimestamp(stat_result.st_mtime).strftime("%Y/%m/%d %H:%M:%S")

        return create_time, update_time

    def refresh(self, event=None):
        self.listbox.delete(0, "end")
        self.display_todo()

    def set_value_for_combbox(self):
        self.combbox["value"] = ["all"] + [dir_name.split("\\")[-1] for dir_name in self.todo.get_dir_name_keys()]

    def mainloop(self):
        self.root.mainloop()


if __name__ == "__main__":
    todo_display = TodoDisplay()
    todo_display.display_todo()
    todo_display.mainloop()

Mit dem Objekt ** Tkinter ** zeigen wir eine Liste von ** TODO-Dateien ** an, die in ** todo.py ** gesucht wurden.

GUI-Objektteile

gui_object.py


from tkinter import *
import tkinter as tk
import tkinter.ttk as ttk


class Frame(tk.Frame):
    def __init__(self, master=None):
        tk.Frame.__init__(self, master)
        self.grid(column=0, row=0)
        self["width"] = 100
        self["height"] = 100
        self["padx"] = 20
        self["pady"] = 20


class Button(tk.Button):
    def __init__(self, master=None):
        tk.Button.__init__(self, master)

        self["height"] = 2
        self["width"] = 20
        self["font"] = ("Helvetica", 15)


class RefreshButton(Button):
    def __init__(self, master=None,):
        Button.__init__(self, master)


class Combobox(ttk.Combobox):
    def __init__(self, master=None):
        ttk.Combobox.__init__(self, master)

        self["font"] = ("Helvetica", 20)


class Text(tk.Text):
    def __init__(self, master=None):
        tk.Text.__init__(self, master)
        self["width"] = 100
        self["height"] = 10


class Listbox(tk.Listbox):
    def __init__(self, master=None, master_of_detail_text=None):
        scrollbar = Scrollbar(master)
        scrollbar.pack(side=RIGHT, fill=Y)
        tk.Listbox.__init__(self, master, yscrollcommand=scrollbar.set, selectmode=EXTENDED)

        self.pack(side=LEFT, fill=BOTH)
        self["width"] = 100
        self["height"] = 10
        self["font"] = ("Helvetica", 12)
        self.master = master
        self.master_of_detail_text = master_of_detail_text
        self.text = Text(self.master_of_detail_text)

        scrollbar["command"] = self.yview
        self.bind("<Double-Button-1>", self.show_detail)
        self.bind("<Return>", self.show_detail)

        self.todo_list = {}

    def show_detail(self, event=None):
        self.text.destroy()
        self.text = Text(self.master_of_detail_text)
        self.text.insert(END, self.read_detail_of_todo(self.index(ACTIVE)))
        self.text.pack()

    def set_todo_list(self, todo_list_dict):
        self.todo_list = todo_list_dict

    def read_detail_of_todo(self, index):
        path = self.todo_list[index]
        with open(path, encoding="utf_8") as f:
            return f.read()

Einstellungen werden für verschiedene ** Tkinter ** -Objekte vorgenommen, die in ** display.py ** verwendet werden.

Ich passe hauptsächlich das Aussehen an.

Am Ende

Es war eine lustige und glückliche Zeit, eine Anwendung mit einem festen Thema zu erstellen.

Ich hoffe, dass diese TODO-App in Zukunft nützlich sein wird.

Recommended Posts

Wenn Sie eine TODO-Anwendung (verteilt) jetzt nur mit Python erstellen möchten
Wenn Sie eine TODO-Anwendung (verteilt) nur mit Python-Extension 1 erstellen möchten
Wenn Sie eine Windows-App (exe) erstellen möchten, die jetzt nur mit Python verwendet werden kann
Ich habe versucht, eine ToDo-App mit einer Flasche mit Python zu erstellen
Ich möchte eine Webanwendung mit React und Python Flask erstellen
Wenn Sie einen Discord-Bot mit Python erstellen möchten, verwenden wir ein Framework
Wenn Sie einer Variablen in Python einen CSV-Export zuweisen möchten
[Python] Wenn Sie ein Streudiagramm mehrerer Cluster zeichnen möchten
Ich möchte ein Spiel mit Python machen
Wenn Sie Word Cloud erstellen möchten.
Wenn Sie den Wert mithilfe von Auswahlmöglichkeiten in der Vorlage im Django-Modell anzeigen möchten
(Python) Versuchen Sie, eine Webanwendung mit Django zu entwickeln
So erstellen Sie ein Python-Paket mit VS Code
[Python] Ich möchte aus einer verschachtelten Liste einen Taple machen
[Django] Memorandum, wenn Sie asynchron kommunizieren möchten [Python3]
So verschieben Sie ein zweidimensionales Array nur mit Python [Hinweis]
Ich habe eine Stoppuhr mit tkinter mit Python gemacht
Ich möchte eine schöne Ergänzung zu input () in Python hinzufügen
Wenn Sie einen UNIX-Befehl in Python ausführen möchten
Ich möchte einen Sprachwechsler mit Python und SPTK in Bezug auf eine berühmte Site erstellen
Wenn Sie Datenwissenschaftler werden möchten, beginnen Sie mit Kaggle
Schreiben Sie Python nicht, wenn Sie es mit Python beschleunigen möchten
Was tun, wenn in Python minus Null angezeigt wird?
Ich habe versucht, mit Python einen regulären Ausdruck für "Betrag" zu erstellen
Ich habe versucht, mit Python einen regulären Ausdruck von "Zeit" zu erstellen
Ich möchte wissen, ob Sie Python auf Mac ・ Iroha installieren
Ich habe versucht, mit Python einen regulären Ausdruck von "Datum" zu erstellen
Ich habe versucht, mit Python eine 2-Kanal-Post-Benachrichtigungsanwendung zu erstellen
[Einführung] Ich möchte mit Python einen Mastodon-Bot erstellen! 【Anfänger】
Überprüfen Sie, ob Sie in Python eine Verbindung zu einem TCP-Port herstellen können
Wenn Sie mehrere Zeichen in einer Zeichenfolge ersetzen möchten, ohne reguläre Ausdrücke in der Python3-Serie zu verwenden
Wenn Sie einen Singleton in Python möchten, stellen Sie sich das Modul als Singleton vor
[Einführung in die Udemy Python3 + -Anwendung] 33. if-Anweisung
Was tun, wenn bei Verwendung von Python mit der NetBeans-IDE die Warnung "Falsche Python-Plattform" angezeigt wird?
[Python] Wie man eine Klasse iterierbar macht
Wenn Sie awsebcli in CircleCI aufnehmen möchten, geben Sie die Python-Version an
Ich möchte eine Python-Umgebung erstellen
[Streamlit] Ich hasse JavaScript, deshalb erstelle ich eine Webanwendung nur mit Python
Wenn Sie Wörter in Python zählen möchten, können Sie bequem Counter verwenden.
Ich möchte Affenpatches nur teilweise sicher mit Python machen
Ich habe eine einfache Mail-Sendeanwendung mit tkinter von Python erstellt
Verwenden Sie PIL in Python, um nur die gewünschten Daten aus Exif zu extrahieren
[Python] Smasher hat versucht, den Video-Ladevorgang mithilfe eines Generators zu einer Funktion zu machen
Was tun, wenn "Python nicht konfiguriert" angezeigt wird? Verwenden von PyDev in Eclipse
Ich möchte Matplotlib zu einem dunklen Thema machen
Ein Memorandum, um WebDAV nur mit Nginx zu erstellen
Möchten Sie einen Twitter-Lebenslauf erstellen?
Ich möchte mit Python ein Fenster erstellen
Ich möchte mit Python eine E-Mail von Google Mail senden.
Versuchen Sie, in Python einen "Entschlüsselungs" -Code zu erstellen
Schritte zum Entwickeln einer Webanwendung in Python
Versuchen Sie, mit Python eine Diedergruppe zu bilden
Ich möchte C ++ - Code aus Python-Code erstellen!
Lassen Sie uns mit SWIG ein Modul für Python erstellen
Ich möchte mit Python in eine Datei schreiben
Ich habe ein ○ ✕ Spiel mit TensorFlow gemacht
Lark grundlegende Erklärung (machen Sie einen Shell-ähnlichen Kerl mit Python, Lark)
Eine Funktionsnotiz, die nützlich ist, wenn Sie den Debugger aufrufen möchten, wenn beim Ausführen eines Python-Skripts ein Fehler auftritt.
Ansible selbst erstellte Modulerstellung - Teil 4: Leben, das Sie ohne Named Pipe machen möchten (vollständig) -