データを扱うアプリケーションにはCRUD(クラッド)という基本構造があります。
このCRUDを知っておくと、全てのアプリケーションに応用が効きます。
この記事ではそんなCRUDについて、前編後編に分けて解説します。
CRUDとは?
CRUDとは、
- Creste(登録)
- Read(表示)
- Update(更新)
- Delete(削除)
の頭文字を取ったものです。
どんなデータでも、
「登録」して、
「表示」して、
「更新」して、
「削除」することによってアプリケーションは成り立っています。
違いはデータがどこにあるのか(データベースにあるのか、ファイルでもっているのか、etc.)、表示する方法は何か(Webシステムなのか、GUIアプリなのか、etc.)、などの違いだけです。
だから、このCRUDをそれぞれ作りこむことで、アプリケーションは基本成り立つのです。
そこに、保存機能やログイン機能などを付ければ、アプリケーションの完成です。
サンプルで見るCRUD
それでは、CRUDのサンプルを示します。
今回はPython+tkinterで書きます。tkinterの説明は割愛します。
このアプリケーションは、一行のテキストを入力して、それを一覧で表示するものです。保存機能などはついていません。
なお、エラーチェックも最小限ですので、そこは適宜お読み替えください。
まず、アプリケーションの基本構造を示します。
import tkinter as tk
import tkinter.ttk as ttk
class Application(tk.Frame):
    def __init__(self,master):
        super().__init__(master)
        self.data = []
        self.master = master
        self.master.title("CRUDサンプル")
        self.num = []
        self.text = []
        button = tk.Button(self.master, text='追加', command=self.create)
        button.grid(row=0, column=0)
        self.row_val = tk.IntVar(self.master)
        row = ttk.Entry(self.master, textvariable=self.row_val)
        row.grid(row=0, column=1)
        button = tk.Button(self.master, text='を更新', command=self.update)
        button.grid(row=0, column=2)
        button = tk.Button(self.master, text='を削除', command=self.delete)
        button.grid(row=0, column=3)
    def create(self):
        ・・・
    def update(self):
        ・・・
    def delete(self):
        ・・・
    def show(self):
        ・・・
win = tk.Tk()
app = Application(master=win)
app.mainloop()

初期化関数ではウィジットを配置して、クラスのデータを準備しています。ここで、
data:テキストの配列
num:テキスト表示領域の行番号(Label)の配列
text:テキスト(Label)の配列
です。
Read(表示)
順番が逆になりますが、表示から見ていきましょう。
    def show(self):
        for num in self.num:
            num.destroy()
        for text in self.text:
            text.destroy()
        self.num = []
        self.text = []
        for i,d in enumerate(self.data):
            self.num.append(tk.Label(self.master, text=i+1))
            self.num[i].grid(row=i+2, column=0)
            self.text.append(tk.Label(self.master, text=d))
            self.text[i].grid(row=i+2, column=1, columnspan=3)
まず今表示されている行番号とテキストのウィジットを壊します。全て消します。
その後で、self.dataの一つ一つを行番号と共に表示していきます。
Create(登録)
次に登録です。
    def create(self):
        class NewEntry(tk.Frame):
            def __init__(self, master, parent):
                super().__init__(master)
                self.master = master
                self.parent = parent
                self.master.title("CREATE")
                self.text_val = tk.StringVar(self.master)
                text = ttk.Entry(self.master, textvariable=self.text_val)
                text.grid(row=0, column=0)
                button = tk.Button(self.master, text='OK', command=self.ok)
                button.grid(row=1, column=0)
            def ok(self):
                self.parent.create2(self.text_val.get().strip())
                self.master.destroy()
        win = tk.Tk()
        app = NewEntry(master=win, parent=self)
        app.mainloop()
    def create2(self, new_str):
        self.data.append(new_str)
        self.show()
入力用ウィンドゥを出して、値をcreate2でもらっています。
create2ですることは、self.dataへのデータの追加と、表示をコールすることです。
例えば2行追加してみましょう。



Update(変更)
変更は登録より少し長いです。
    def update(self):
        try:
            if self.row_val.get() < 1 or self.row_val.get() > len(self.data):
                return
        except:
            return
        class UpdateEntry(tk.Frame):
            def __init__(self, master, parent, old_str):
                super().__init__(master)
                self.master = master
                self.parent = parent
                self.master.title("UPDATE")
                self.text_val = tk.StringVar(self.master)
                self.text_val.set(old_str)
                text = ttk.Entry(self.master, textvariable=self.text_val)
                text.grid(row=0, column=0)
                button = tk.Button(self.master, text='OK', command=self.ok)
                button.grid(row=1, column=0)
            def ok(self):
                self.parent.update2(self.text_val.get().strip())
                self.master.destroy()
        win = tk.Tk()
        app = UpdateEntry(master=win, parent=self, old_str=self.data[self.row_val.get()-1])
        app.mainloop()
        
    def update2(self, new_str):
        self.data[self.row_val.get()-1] = new_str
        self.show()
行数のチェックと、入力画面に初期値を渡すところが登録との違いです。
update2で入力画面から変更後の値をもらって、dataの該当する行数のところを書き換え、表示を呼んでいます。
例えば2行目を書き換えてみましょう。


Delete(削除)
削除は簡単です。
    def delete(self):
        try:
            if self.row_val.get() < 1 or self.row_val.get() > len(self.data):
                return
        except:
            return
        del self.data[self.row_val.get()-1]
        self.show()
まず行数のチェックをして、その後でdataの該当する要素を削除して、表示を呼ぶだけです。
1行目を削除してみます。

ここで、プログラムの全体を再掲します。
import tkinter as tk
import tkinter.ttk as ttk
class Application(tk.Frame):
    def __init__(self,master):
        super().__init__(master)
        self.data = []
        self.master = master
        self.master.title("CRUDサンプル")
        self.num = []
        self.text = []
        button = tk.Button(self.master, text='追加', command=self.create)
        button.grid(row=0, column=0)
        self.row_val = tk.IntVar(self.master)
        row = ttk.Entry(self.master, textvariable=self.row_val)
        row.grid(row=0, column=1)
        button = tk.Button(self.master, text='を更新', command=self.update)
        button.grid(row=0, column=2)
        button = tk.Button(self.master, text='を削除', command=self.delete)
        button.grid(row=0, column=3)
    def create(self):
        class NewEntry(tk.Frame):
            def __init__(self, master, parent):
                super().__init__(master)
                self.master = master
                self.parent = parent
                self.master.title("CREATE")
                self.text_val = tk.StringVar(self.master)
                text = ttk.Entry(self.master, textvariable=self.text_val)
                text.grid(row=0, column=0)
                button = tk.Button(self.master, text='OK', command=self.ok)
                button.grid(row=1, column=0)
            def ok(self):
                self.parent.create2(self.text_val.get().strip())
                self.master.destroy()
        win = tk.Tk()
        app = NewEntry(master=win, parent=self)
        app.mainloop()
    def create2(self, new_str):
        self.data.append(new_str)
        self.show()
    def update(self):
        try:
            if self.row_val.get() < 1 or self.row_val.get() > len(self.data):
                return
        except:
            return
        class UpdateEntry(tk.Frame):
            def __init__(self, master, parent, old_str):
                super().__init__(master)
                self.master = master
                self.parent = parent
                self.master.title("UPDATE")
                self.text_val = tk.StringVar(self.master)
                self.text_val.set(old_str)
                text = ttk.Entry(self.master, textvariable=self.text_val)
                text.grid(row=0, column=0)
                button = tk.Button(self.master, text='OK', command=self.ok)
                button.grid(row=1, column=0)
            def ok(self):
                self.parent.update2(self.text_val.get().strip())
                self.master.destroy()
        win = tk.Tk()
        app = UpdateEntry(master=win, parent=self, old_str=self.data[self.row_val.get()-1])
        app.mainloop()
        
    def update2(self, new_str):
        self.data[self.row_val.get()-1] = new_str
        self.show()
    def delete(self):
        try:
            if self.row_val.get() < 1 or self.row_val.get() > len(self.data):
                return
        except:
            return
        del self.data[self.row_val.get()-1]
        self.show()
    def show(self):
        for num in self.num:
            num.destroy()
        for text in self.text:
            text.destroy()
        self.num = []
        self.text = []
        for i,d in enumerate(self.data):
            self.num.append(tk.Label(self.master, text=i+1))
            self.num[i].grid(row=i+2, column=0)
            self.text.append(tk.Label(self.master, text=d))
            self.text[i].grid(row=i+2, column=1, columnspan=3)
win = tk.Tk()
app = Application(master=win)
app.mainloop()
まとめ・アプリケーションはCRUDを拡張したもの
この記事ではCRUDについて解説しました。
繰り返しになりますが、どんなアプリケーションでもCRUDを拡張したものです。このサイクルが分かっていればデータを扱うことができます。
今回のサンプルプログラムを、データベースにアクセスするものにしたり、Flaskのアプリケーションにアレンジしてみたりしてください。それは立派なデータベースシステムですし、Webシステムです。
アプリケーションがやっていることは、複雑そうに見えて基本構造は単純です。
あとはどれくらい応用の幅が広がるかにかかってきます。スキルは常に磨きましょう。

 
			 
			 
			 
			 
			 
			