Pythonでファイル処理のGUIプログラムを作ってみた！

#本記事について
本記事は[Python：処理ファイルをGUIから選択する方法](https://qiita.com/chanmaru/items/1b64aa91dcd45ad91540)の続編になります。
もし、まだ閲覧されていない方は是非、読んでみて下さい！

[Python：処理ファイルをGUIから選択する方法](https://qiita.com/chanmaru/items/1b64aa91dcd45ad91540)では、Tkinterを使ってファイル選択ダイアログを表示させる方法を紹介しました。
ただ、これでは少し物足りない・・・。
ということで、もう少し踏みこんだファイルを処理GUIプログラムを作成してみました。

OSはWindows7、Pythonは3.6.3で動作検証しています。

参考サイト：[Tkinter による GUI プログラミング](http://python.keicode.com/advanced/tkinter.php)

#作成したプログラム
早速、作成したプログラムを紹介します。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/250196/5a7bb64f-2e08-ebc4-32f8-4d9c2782265f.png)

参照ボタンをクリックするとファイル選択ダイアログが表示され、ファイル選択ができます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/250196/91de69d2-9ca4-4185-202d-139bc8ff6220.png)

ファイルを選択すると、選択したファイルパスが表示されます。
※ここは単にファイル名だけでも良いかもしれませんね。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/250196/6c7b8e08-b4f6-6371-5c99-1a2feba504c8.png)

Startボタンをクリックすると、選択したファイルに対して処理が開始されます。
※実際は選択したファイルに対して何かしらの処理を実行しますが、今回はダミーで選択ファイルの絶対パスをメッセージボックスにて表示する処理を実行しています。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/250196/17156106-3582-a553-9090-05a8bf80c369.png)

#ソースコードの紹介
プログラムのソースコードは以下のとおりです。

```Python:FileReference.py
import os,sys
from tkinter import *
from tkinter import ttk
from tkinter import filedialog
from tkinter import messagebox

# 参照ボタンのイベント
# button1クリック時の処理
def button1_clicked():
    fTyp = [("","*")]
    iDir = os.path.abspath(os.path.dirname(__file__))
    filepath = filedialog.askopenfilename(filetypes = fTyp,initialdir = iDir)
    file1.set(filepath)

# button2クリック時の処理
def button2_clicked():
    messagebox.showinfo('FileReference Tool', u'参照ファイルは↓↓\n' + file1.get())

if __name__ == '__main__':
    # rootの作成
    root = Tk()
    root.title('FileReference Tool')
    root.resizable(False, False)

    # Frame1の作成
    frame1 = ttk.Frame(root, padding=10)
    frame1.grid()

    # 参照ボタンの作成
    button1 = ttk.Button(root, text=u'参照', command=button1_clicked)
    button1.grid(row=0, column=3)

    # ラベルの作成
    # 「ファイル」ラベルの作成
    s = StringVar()
    s.set('ファイル>>')
    label1 = ttk.Label(frame1, textvariable=s)
    label1.grid(row=0, column=0)

    # 参照ファイルパス表示ラベルの作成
    file1 = StringVar()
    file1_entry = ttk.Entry(frame1, textvariable=file1, width=50)
    file1_entry.grid(row=0, column=2)

    # Frame2の作成
    frame2 = ttk.Frame(root, padding=(0,5))
    frame2.grid(row=1)

    # Startボタンの作成
    button2 = ttk.Button(frame2, text='Start', command=button2_clicked)
    button2.pack(side=LEFT)

    # Cancelボタンの作成
    button3 = ttk.Button(frame2, text='Cancel', command=quit)
    button3.pack(side=LEFT)

    root.mainloop()
```

#ソースコードの解説
##必要モジュール
インポートしているモジュールは以下のとおりです。

```Python
import os,sys
from tkinter import *
from tkinter import ttk
from tkinter import filedialog
from tkinter import messagebox
```

画面作成では、```tkinter```と```tkinter.ttk```を使っていて、他のモジュールはボタンクリック時の処理で使っています。

##rootの作成
Tkinterではroot作成は必須です。
rootから木構造で各部品を構築していきます。

```Python
# rootの作成
root = Tk()
root.title('FileReference Tool')
root.resizable(False, False)
```

4行目の```root.resizable```にて、ウィンドウサイズの変更を無効にしています。

##Frameの作成
root配下に部品を配置する枠を作成します。
rootとFrameはお決まりごとのような感じなので、まずrootとFrameを作成すると覚えておくと良いと思います。

```Python
# Frame1の作成
frame1 = ttk.Frame(root, padding=10)
frame1.grid()
```

##参照ボタンの作成
参照ボタンを作成します。作成には、```ttk.Button```を使います。

```Python
# 参照ボタンの作成
button1 = ttk.Button(frame1, text=u'参照', command=button1_clicked)
button1.grid(row=0, column=3)
```

参照ボタンはframe1配下に構築します。
2行目のcommandにてクリック時の処理内容を記載しています。ここでは、関数```button1_clicked```を動かしています。

```Python
def button1_clicked():
    fTyp = [("","*")]
    iDir = os.path.abspath(os.path.dirname(__file__))
    filepath = filedialog.askopenfilename(filetypes = fTyp,initialdir = iDir)
    file1.set(filepath)
```

詳しい説明は「[Python：処理ファイルをGUIから選択する方法](https://qiita.com/chanmaru/items/1b64aa91dcd45ad91540)」に記載しているの割愛しますが、最後の```file1.set(filepath)```にてファイルパスの値をTkinterにて表示可能にしています。

3行目の```button1.grid(row=0, column=3)```にて部品を配置しています。
gridは２次元的配置をする際に用います。今回は0行目の3列目に配置しています。
配置方法は他にも、縦または横に１次元的に配列するpackと、配置を直接指定するplaceがあります。
うまく使い分けたいですね！


##ラベルの作成
ウィンドウに表示させるラベルを作成します。まずは、「ファイル>>」という文字。

```Python
# 「ファイル>>」ラベルの作成
s = StringVar()
s.set('ファイル>>')
label1 = ttk.Label(frame1, textvariable=s)
label1.grid(row=0, column=0)
```

詳しくはないのですが、ラベル表示においてStringVarというサブクラスを用いるようで、2行目、3行目は少しお決まりごとのように記述しています。

ファイルパスの表示は以下のとおりです。

```Python
# 参照ファイルパス表示ラベルの作成
file1 = StringVar()
file1_entry = ttk.Entry(frame1, textvariable=file1, width=50)
file1_entry.grid(row=0, column=2)
```

参照ボタン後の処理関数において、```file1```にファイルパスの値を格納しているため、参照ボタンクリック後には、本ラベルにファイルパスの値が表示されます。
ここがWebサイトにもなかなか記載がなくて、少し苦労しました。

##処理実行ボタンと中止ボタンの作成
処理実行ボタンと中止ボタンは、参照ボタンと同じ方法で作成しますが、frame2という別枠にて表示しています。

```Python
# Frame2の作成
frame2 = ttk.Frame(root, padding=(0,5))
frame2.grid(row=1)

# Startボタンの作成
button2 = ttk.Button(frame2, text='Start', command=button2_clicked)
button2.pack(side=LEFT)

# Cancelボタンの作成
button3 = ttk.Button(frame2, text='Cancel', command=quit)
button3.pack(side=LEFT)
```

StartとCancelボタンの配置にはpackを使っています。
正直、配置については勉強不足で、色々試した結果、上記の値が一番見た目が良くなりました。

Startボタンクリック時には、以下の関数処理が実行されます。

```Python
def button2_clicked():
    messagebox.showinfo('FileReference Tool', u'参照ファイルは↓↓\n' + file1.get())
```

メッセージボックスの表示ですね！
file1はStringVarというサブオブジェクトであり、実際の値を表示するために```get()```メソッドを用います。

##最後のおまじない
Tkinterでは、最後に追加した部品でmainloopメソッドを実行する必要があり、以下の1行は必須です。

```Python
root.mainloop()
```

#おわりに
私自身まだまだ勉強不足ですが、なんとかファイル実行GUIプログラムを作成できました。
ファイル参照してから実行する流れは基本なので、かなり汎用的に利用できるのではないかと思っています。
今回は標準モジュールであるTkinterを用いましたが、wxpythonやPyQtも使ってみたいです！