Si vous souhaitez créer une application TODO (distribuée) maintenant en utilisant uniquement Python

Résumé de cet article

Cet article concerne le festival d'été Qiita 2020 "Si vous voulez créer △△ (application) en utilisant uniquement 〇〇 (langue)" Il présente l'application ** TODO (distribuée) ** créée sous forme de thème et explique comment l'implémenter.

J'utilise ** Python3 (ver 3.7) ** et j'ai confirmé l'opération sous Windows 10.

Le code se trouve sur le GitHub ci-dessous. Sentez-vous libre de l'utiliser.

[Code] 1

Qu'est-ce qu'une application TODO (distribuée)?

Apparence

L'application est la suivante.

todo.png

todo.gif

Il y a un endroit pour afficher la liste TODO en bas.

Vous pouvez sélectionner une chaîne dans le menu déroulant pour afficher un TODO spécifique, et elle sera affichée en appuyant sur le bouton de mise à jour.

Sélectionnez une liste TODO pour voir plus de détails dans la liste.

une fonction

Il met en œuvre trois fonctions principales.

Répertorier les fichiers TODO stockés dans plusieurs dossiers

function_一覧表示.png

Cette fonction recherche les fichiers TODO enregistrés dans plusieurs dossiers spécifiés et les affiche dans une liste à l'écran.

Par exemple, supposons que vous stockiez un ** fichier TODO ** appelé .txt ** dans un dossier appelé ** F: \ Document \ Qiita ** qui publie une application todo faite uniquement avec ** python. Dans ce fichier, les détails de TODO, la date limite de publication de l'article en cours de rédaction, la date limite de publication, etc. sont inscrits.

D'autre part, supposons qu'il y ait un autre ** fichier TODO ** dans le dossier ** F: \ Document \ python \ django **.

Le problème avec cette situation est que les ** fichiers TODO ** sont ** distribués **.

Bien sûr, vous pouvez créer un ** dossier TODO ** et y placer le ** fichier TODO **, mais puisque vous avez créé et organisé la hiérarchie des dossiers à votre manière, les fichiers associés sont, par exemple, ** TODO. Je veux mettre le fichier ** dans le même dossier. De plus, des informations importantes peuvent être ajoutées, telles que l'ajout du contenu recherché au ** fichier TODO **.

Afin de résoudre le problème ci-dessus, des ** fichiers TODO ** peuvent être distribués.

Répertorier uniquement les TODO stockés dans un dossier spécifique

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

Cette fonction répertorie uniquement les ** fichiers TODO ** dans un dossier particulier.

Lorsque le nombre de ** fichiers TODO ** augmente, il est difficile de trouver le ** fichier TODO ** souhaité dans tous les ** fichiers TODO **.

Par conséquent, nous avons rendu possible la sélection d'un dossier dans le menu déroulant afin que seuls les ** fichiers TODO ** stockés dans un dossier spécifique puissent être affichés.

Afficher le contenu détaillé du fichier TODO

function_詳細表示.png

Cette fonction affiche les détails en bas de l'écran lorsque vous cliquez sur la liste affichée des ** fichiers TODO **.

Les détails sont décrits dans le ** fichier TODO **.

En gros, il peut suffire d'écrire un ** TODO ** spécifique (que faire) avec le nom du fichier. Cependant, j'ai pensé qu'il serait préférable de voir les progrès et le contenu de l'enquête, alors je l'ai mise en œuvre.

Comment utiliser

Téléchargez le code depuis [GitHub] 1 au début de cet article et placez-le dans un dossier.

Exécutez ** display.py ** pour lancer l'interface graphique.

python display.py

Le fichier de configuration est un fichier nommé ** config.ini ** et est décrit dans le format suivant.

[Dir_names]
#Le nom affiché dans le menu déroulant=Chemin absolu du dossier contenant le fichier TODO
#Exemple
qiita=F:\Document\800_Auto-apprentissage informatique\09_python\51_Qiita

[File_names]
#Le nom du fichier que vous souhaitez afficher dans la liste TODO. Caractère générique(*)Vous pouvez utiliser.
#Exemple

#Fichiers avec la chaîne todo au début
todo=todo*

#Fichiers avec l'extension py
python=*.py

** * Veuillez noter que la recherche peut prendre un certain temps s'il y a un grand nombre de dossiers et de fichiers sous le nom de dossier répertorié. ** ** ** C'est une histoire extrême, mais si vous écrivez C: \ dans le nom du dossier, cela prendra un temps considérable pour afficher la liste TODO. ** **

** Le code de caractère du fichier TODO doit être UTF-8. L'écran de détails ne s'affiche pas. ** **

À propos de la mise en œuvre

Rechercher des fichiers

operate_file_1.py


import os
import fnmatch
#root:Nom du répertoire
#patterns:Prend en charge les caractères génériques de type shell Unix. Modèle de nom de fichier
#yeild_folders:S'il faut lire les fichiers dans le sous-répertoire.

def all_files(root, patterns = "*", single_level=False, yeild_folders=False):
#split:";"Vous pouvez spécifier plusieurs modèles avec.;Ne peut pas être inclus dans le modèle.
    patterns = patterns.split(";")

#os.Passez le nom du chemin du répertoire, le nom du répertoire et le nom du fichier sous le répertoire spécifié par walk.
    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 renvoie True si le nom correspond au modèle.
                if fnmatch.fnmatch(name, pattern):
                    yield os.path.join(path, name)
                    break
        if single_level:
            break

Ce sera le code décrit dans le livre de recettes Python.

Python Cookbook 2nd Edition (Page 89, 2.16 Directory Tree Search) par Alex Martelli, Anna Martelli Ravenscroft, David Ascher, Masao Kamozawa, Hitoshi Toyama, Satoshi Yoshida, Sadaki Yoshimune, etc. Traduit par O'Reilly Japan ISBN978- 4-87311-276-3

Ce que nous faisons est de rechercher une correspondance à partir du nom de répertoire et de nom de fichier reçus et de renvoyer le résultat.

todo search

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

Il s'agit d'une classe qui lit les paramètres de ** config.ini ** et recherche le fichier à l'aide de la fonction décrite dans ** operator_file_1.py **.

Utilisez le module intégré à python appelé ** [configparser] 2 ** pour lire la valeur du fichier de configuration.

** search \ _file ** recherche toute la recherche, ** limit \ _ search \ _file ** recherche uniquement le dossier spécifié.

affichage todo

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"] = "mise à jour"
        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(["Créer", create_time, "mise à jour", 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()

En utilisant l'objet ** Tkinter **, nous affichons une liste de ** fichiers TODO ** recherchés dans ** todo.py **.

Parties d'objet GUI

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()

Les paramètres sont définis pour divers objets ** Tkinter ** utilisés dans ** display.py **.

J'ajuste principalement l'apparence.

À la fin

C'était un moment amusant et heureux pour créer une application avec un thème fixe.

J'espère que cette application TODO sera utile à l'avenir.

Recommended Posts

Si vous souhaitez créer une application TODO (distribuée) maintenant en utilisant uniquement Python
Si vous souhaitez créer une application TODO (distribuée) en utilisant uniquement Python-Extension 1
Si vous souhaitez créer une application Windows (exe) qui peut être utilisée maintenant en utilisant uniquement Python
J'ai essayé de créer une application todo en utilisant une bouteille avec python
Je souhaite créer une application Web en utilisant React et Python flask
Si vous voulez créer un bot discord avec python, utilisons un framework
Si vous souhaitez affecter une exportation csv à une variable en python
[Python] Si vous souhaitez dessiner un diagramme de dispersion de plusieurs clusters
Je veux faire un jeu avec Python
Si vous souhaitez créer Word Cloud.
Si vous souhaitez afficher la valeur à l'aide des choix du modèle dans le modèle Django
(Python) Essayez de développer une application Web en utilisant Django
Comment créer un package Python à l'aide de VS Code
[Python] Je veux faire d'une liste imbriquée un taple
[Django] Mémorandum lorsque vous souhaitez communiquer de manière asynchrone [Python3]
Comment transloquer un tableau à deux dimensions en utilisant uniquement python [Note]
J'ai fait un chronomètre en utilisant tkinter avec python
Je veux ajouter un joli complément à input () en python
Lorsque vous souhaitez lancer une commande UNIX sur Python
Je veux faire un changeur de voix en utilisant Python et SPTK en référence à un site célèbre
Si vous souhaitez devenir data scientist, commencez par Kaggle
N'écrivez pas Python si vous voulez l'accélérer avec Python
Que faire si vous obtenez moins zéro en Python
J'ai essayé de créer une expression régulière de "montant" en utilisant Python
J'ai essayé de créer une expression régulière de "temps" en utilisant Python
Je veux savoir si vous installez Python sur Mac ・ Iroha
J'ai essayé de créer une expression régulière de "date" en utilisant Python
J'ai essayé de créer une application de notification de publication à 2 canaux avec Python
[Introduction] Je veux créer un robot Mastodon avec Python! 【Débutants】
Vérifiez si vous pouvez vous connecter à un port TCP en Python
Lorsque vous souhaitez remplacer plusieurs caractères dans une chaîne de caractères sans utiliser d'expressions régulières dans la série python3
Si vous voulez un singleton en python, considérez le module comme un singleton
[Introduction à l'application Udemy Python3 +] 33. instruction if
Que faire si vous obtenez un avertissement "Mauvaise plateforme Python" lors de l'utilisation de Python avec l'EDI NetBeans
[Python] Comment rendre une classe itérable
Si vous souhaitez inclure awsebcli dans CircleCI, spécifiez la version de python
Je veux créer un environnement Python
[Streamlit] Je déteste JavaScript, donc je crée une application Web uniquement avec Python
Si vous souhaitez compter les mots en Python, il est pratique d'utiliser Counter.
Je veux faire un patch monkey seulement en partie en toute sécurité avec Python
J'ai fait une application d'envoi de courrier simple avec tkinter de Python
Utilisez PIL en Python pour extraire uniquement les données souhaitées d'Exif
[Python] Smasher a essayé de faire du processus de chargement de la vidéo une fonction à l'aide d'un générateur
Que faire si vous obtenez «Python non configuré». Utilisation de PyDev dans Eclipse
Je veux faire de matplotlib un thème sombre
Un mémorandum pour faire WebDAV uniquement avec nginx
Souhaitez-vous créer un CV Twitter?
Je veux créer une fenêtre avec Python
Je souhaite envoyer un e-mail depuis Gmail en utilisant Python.
Essayez de créer un code de "décryptage" en Python
Étapes pour développer une application Web en Python
Essayez de créer un groupe de dièdre avec Python
Je veux créer du code C ++ à partir de code Python!
Faisons un module pour Python en utilisant SWIG
Je veux écrire dans un fichier avec Python
J'ai créé un jeu ○ ✕ avec TensorFlow
Explication de base de Lark (faites un gars comme une coquille avec Python, Lark)
Un mémo de fonction utile lorsque vous souhaitez entrer dans le débogueur si une erreur se produit lorsque vous exécutez un script Python.
Création d'un module personnalisé Ansible - Partie 4: La vie que vous voulez créer sans tuyau nommé (complète) -