tkinterを使ってテキストエディタのアプリを作ってみた　~PART1~

python学習のアウトプットです。今回はtkinterを使用し、テキストエディタのアプリを作ってみました。メールなどに使われる定形文をストックし、必要に応じて使えるアプリです。まずはアプリを紹介します。

メインウインドウ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2631873/62d66ac2-c9f2-9398-4e7b-16ec604b5094.png)

サブウインドウ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2631873/2d83f6af-3209-5d68-f331-9d3ec0b76b3d.png)

アプリの機能としては、サブウインドウのフレームラベルRegistration内のFixed Phraseのテキストボックス内に定形文を入力し、Saveボタンを押下すると下のSave Slot内選択項目を増やしたり書き換えたりできます。またSave Slot内の定形文をラジオボタンにて選択し、Setボタンを押下すると、メインウインドウのテキストボックス内に定形文をセットすることができます。これらの機能を使い、メールの文面を作成していきます。

では、次にコードを記載します。

```py
# インポート
import tkinter as tk
from tkinter import ttk
import configparser
from tkinter import filedialog

# configparserのインスタンス化
config = configparser.ConfigParser()
# 読み込む設定ファイルを指定
config.read("setting.ini")

### 関数 ###
def sub_window():
    ### 関数(sub_window) ###
    #設定ファイルへ保存
    def writing_func():
        with open("setting.ini","w") as file:
            config.write(file)
    # Save
    def reg_func():
        # エントリーボックスの値を取得
        reg_phrase = reg_box.get()
        # 定形文の登録
        if radio_value.get() == 1:
            rdio_1["text"] = reg_phrase
            config.set("Fixed Phrase","Phrase1",reg_phrase)
            writing_func()
        elif radio_value.get() == 2:
            rdio_2["text"] = reg_phrase
            config.set("Fixed Phrase","Phrase2",reg_phrase)
            writing_func()
        elif radio_value.get() == 3:
            rdio_3["text"] = reg_phrase
            config.set("Fixed Phrase","Phrase3",reg_phrase)
            writing_func()
        elif radio_value.get() == 4:
            rdio_4["text"] = reg_phrase
            config.set("Fixed Phrase","Phrase4",reg_phrase)
            writing_func()
        elif radio_value.get() == 5:
            rdio_5["text"] = reg_phrase
            config.set("Fixed Phrase","Phrase5",reg_phrase)
            writing_func()
    # Set
    def insert_func():
        # テキストボックスへ定形文の挿入
        if radio_value.get() == 1:
            txtbox.insert("insert",rdio_1["text"])
        elif radio_value.get() == 2:
            txtbox.insert("insert",rdio_2["text"])
        elif radio_value.get() == 3:
            txtbox.insert("insert",rdio_3["text"])
        elif radio_value.get() == 4:
            txtbox.insert("insert",rdio_4["text"])
        elif radio_value.get() == 5:
            txtbox.insert("insert",rdio_5["text"])
    
    ### GUI(sub_window) ###
    # サブウィンドウの作成
    fp_window = tk.Toplevel(root)
    # ラベルフレーム1
    frame1= ttk.Labelframe(fp_window,text = "Registration",
                          padding = 10)
    frame1.pack(padx = 20,pady = 10)
    # ラベル
    reg_label1 = tk.Label(frame1,text = "Fixed Phrase: ")
    reg_label1.pack(side = tk.LEFT,anchor = tk.W)
    # 定形文入力欄
    reg_box = tk.Entry(frame1,width = 50)
    reg_box.pack(side = tk.LEFT)
    # 保存ボタン
    save_button = tk.Button(frame1,text = "Save",command = reg_func)
    save_button.pack(padx = 10,side = tk.LEFT)
    # ラベルフレーム2
    frame2 = ttk.Labelframe(fp_window,text = "Save Slot",
                            paddin = 10)
    frame2.pack(padx = 20,pady = 5,fill = tk.X)
    # ラジオボタン
    radio_value = tk.IntVar()
    read_base = config["Fixed Phrase"]
    rdio_1 = ttk.Radiobutton(frame2,text = 
                            read_base.get("phrase1"),
                            variable = radio_value,value = 1)
    rdio_1.grid(row = 0,column = 0,sticky = tk.W)
    rdio_2 = ttk.Radiobutton(frame2,text = 
                            read_base.get("phrase2"),
                            variable = radio_value,value = 2)
    rdio_2.grid(row = 1,column = 0,sticky = tk.W)
    rdio_3 = ttk.Radiobutton(frame2,text = 
                            read_base.get("phrase3"),
                            variable = radio_value,value = 3)
    rdio_3.grid(row = 2,column = 0,sticky = tk.W)
    rdio_4 = ttk.Radiobutton(frame2,text = 
                            read_base.get("phrase4"),
                            variable = radio_value,value = 4)
    rdio_4.grid(row = 3,column = 0,sticky = tk.W)
    rdio_5 = ttk.Radiobutton(frame2,text = 
                            read_base.get("phrase5"),
                            variable = radio_value,value = 5)
    rdio_5.grid(row = 4,column = 0,sticky = tk.W)
        # Setボタン
    set_button = tk.Button(fp_window,text = "Set",
                          command = insert_func)
    set_button.pack(padx = 20,pady = 10,ipady = 5,fill = tk.X)
    
# Open...
def open_func():
    # 開くテキストファイルのパス
    typ = [("Text","*.txt"),("All Files","*.*")]
    txt_path = tk.filedialog.askopenfilename(filetypes = typ)
    # ファイルが選択された場合データ書き込み
    if len(txt_path) != 0:
            # テキストボックスのデータ消去
            txtbox.delete("1.0","end")
            # テキストボックスへ書込み
            with open(txt_path,"r") as file:
                txtbox.insert("1.end",file.read())
# Save...
def save_func():
            # 保存するテキストファイルのパス
            typ = [("Text","*.txt")]
            txt_path = tk.filedialog.asksaveasfilename(filetypes = typ,
                                                      defaultextension = "txt")
            # ファイルが選択された場合データを保存
            if len(txt_path,) != 0:
                # ファイルへ書込み
                with open(txt_path, "w") as file:
                    # テキストボックスの値を取得
                    data = txtbox.get("1.0","end")
                    file.write(data)
            
### GUI ###
# ウインドウの作成
root = tk.Tk()
# フレーム
frame = ttk.Frame(root,padding = 5)
frame.pack(padx = 5,pady = 5)
# テキストボックス
txtbox = tk.Text(frame,width = 60,height = 20)
# スクロールバー作成
yscroll = tk.Scrollbar(frame,orient = tk.VERTICAL,
                      command = txtbox.yview)
yscroll.pack(side = tk.RIGHT,fill = tk.Y)
txtbox["yscrollcommand"] = yscroll.set
# テキストボックスの配置
txtbox.pack()
# メニューバーの作成
menubar = tk.Menu(root)
root.configure(menu = menubar)
# Fileメニュー
filemenu = tk.Menu(menubar,tearoff = 0)
menubar.add_cascade(label = "File",menu = filemenu)
# Fileメニューの内容
filemenu.add_command(label = "Open...",command = open_func)
filemenu.add_command(label = "Save as...",command = save_func)
filemenu.add_separator()
filemenu.add_command(label = "Exit",
                    command = lambda:root.destroy())
# Helpメニュー
helpmenu = tk.Menu(menubar,tearoff = 0)
menubar.add_cascade(label = "Help",menu = helpmenu)
# >Manual
helpmenu.add_command(label = "Manual")
# 定型文ボタン
fp_button = tk.Button(root, text = "Fixed Phrase",
                      command = sub_window)
fp_button.pack(padx = 10,pady = 10,ipady = 5,fill = tk.X)
# ウインドウ状態の維持
root.mainloop()
```
その他にも、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2631873/1c0d069f-f17f-a201-4346-a833643c1b68.png)
上記の図のメニューバー内のOpen...にてテキストファイルを開き、Save as...にて編集した内容をテキストにて任意のディレクトリに保存する機能がございます。Exitでアプリを終了できます。

次回はコードについて詳細を解説していきます。

エンジニアファーストの会社　<a href="https://www.cre-co.jp/">株式会社CRE-CO</a>　H_M