データを扱うアプリケーションには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システムです。
アプリケーションがやっていることは、複雑そうに見えて基本構造は単純です。
あとはどれくらい応用の幅が広がるかにかかってきます。スキルは常に磨きましょう。
