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