Pythonでファイル選択を行う

Python

Pythonでテキストファイルを加工したり画像処理したりするためにその対象となるファイルを指定するとき、いちいちそのパスを手入力で打ち込んだり、書き換えるのは面倒です。

そこでわざわざ打ち込まなくても普段使っているファイル選択画面からファイルを選ぶだけでそのパスを取得できるようにしましたので、忘れたときのために残しておきます。

まず、ファイル選択を行う最もシンプルなコードは以下のとおりです。

tkinterという、PythonのGUIモジュールのうち標準で搭載されているものを使っています。

from tkinter.filedialog import Open
path=Open().show()
print(path)

これを実行すると、ファイル選択画面が開き、そこでファイルを選び「開く」を押すとそのパスが標準出力にでてきます。

特に何も考えずにファイルを選択するだけならこれで終わりです。

あとはopen()関数(最初のオーが小文字)なんかで開いて処理してください。

from tkinter.filedialog import Open
path=Open().show()
print(path) #ファイルのパスを表示
content=open(path,"r",-1,"utf-8").read() #encodingは適宜指定してください
print(content) #ファイルの中身を表示

ただ、これだけではところどころ小さなストレスを抱えることになる可能性もあるので、自分が使う際、「使ったら便利かな」と思う機能も併せて書き記しておきます。

1.ウィンドウをくっきり表示させる

初っ端からファイル選択の本筋とは関係のないもので申し訳ないのですがデフォルトのままでは、ディスプレイの設定によりウィンドウがボケて表示されてしまいます。

ファイル選択をするたびに「これは気持ち悪いな…」と思っていたのでなんとかします。

解決方法はプログラムの最初に以下の3行を付け加えるだけです。

import ctypes
try:ctypes.windll.shcore.SetProcessDpiAwareness(True)
except:pass

これによりtkinterがディスプレイのDPIに合わせてきれいに表示してくれるようになります。

左が改善後、右が改善前。拡大するとわかりやすいですが、このボヤボヤ感が地味につらいのです。

当然、ファイル選択画面に限らず他のTkinterのウィンドウにも適用されるので使ってみてください。

2.ファイルの拡張子を指定する

ファイル選択画面で特定の拡張子のファイルだけを表示したい場合はOpen()の引数でfiletypesを指定することで実装することができます。

指定する場合は(“{拡張子の説明}”,”{拡張子}”)という組み合わせのタプルを配列に格納してからfiletypesに与えるだけで、例えばPNG画像だけを表示するためには次のように指定します。

from tkinter.filedialog import Open
path=Open(filetypes=[("PNG Image",".png")]).show()
print(path)

このようにPNG画像だけが抽出されて表示されています。

また、タプルを複数個配列に格納することでプルダウンメニューから拡張子を選べるようにもなります。

例えば次のようにすることで、プルダウンメニューからPNG以外のファイルも表示されるように変更できます。

from tkinter.filedialog import Open
path=Open(filetypes=[("PNG Image",".png"),("All Files","*")]).show()
print(path)

では、プレーンテキストやJPEG画像のように同じファイルタイプなのに複数の拡張子を保つ場合はどうしたらいいのでしょうか。

やり方は簡単で、拡張子を「;」(セミコロン)で区切ることで複数種類指定することができます。

from tkinter.filedialog import Open
path=Open(filetypes=[("HTMLファイル","*.htm;*.html"),("All Files","*")]).show()
print(path)

ポイントとしては、タプルの2個めの要素について、拡張子の前に*をつけることで0文字以上の任意の文字列に一致させる必要があるということが挙げられます。もし*をつけないとその文字列に完全一致していないと表示されません。

なお、*と同様に?もワイルドカードとして機能します。このことを利用して以下のようにするとsample001.csvやsample002.csvといったファイル名のみにマッチさせることができます。

from tkinter.filedialog import Open
path=Open(filetypes=[("サンプルテキスト","*|;sample???.csv")]).show()
print(path)

この場合、「|」は単純にファイル名に使用できない文字として採用しているだけです。「<」や「>」を使っても同じことです。

3.複数ファイル選択可能にする

複数ファイルの選択を行うにはOpen()の引数でmultipleTrueに設定します。

from tkinter.filedialog import Open
paths=Open(multiple=True).show()
print(paths)
for path in paths:
    print(path)

これを実行すると、選択したファイルのパスを文字列型で格納したタプルが返りますのでそれを繰り返し処理で取り出せば使うことができます。

('C:/Users/example1.txt', 'C:/Users/example2.txt', 'C:/Users/example3.txt')

C:/Users/example1.txt
C:/Users/example2.txt
C:/Users/example3.txt

4.フォルダを選択する

ファイルではなくフォルダを選択したい場合はOpen()ではなくDirectory()を使います。

from tkinter.filedialog import Directory
path=Directory().show()
print(path)

ただしDirectory()では、filetypesmultipleなどの設定はできません。

5.その他(おまけ)

ファイル選択画面を開いた際、デフォルトで表示されるパスの設定はinitialdir、デフォルトで選択されるファイル名はinitialfile、拡張子を入力しなくても、指定した拡張子を補って開くようにするためにはdefaultextensionをそれぞれ設定します。

また、titleを設定すればファイル選択画面のタイトルを変更できます。

from tkinter.filedialog import Open

option = {
    "filetypes":[("PNG Image",".png"),("All Files",".*")],
    "initialdir":"C:/Users",
    "initialfile":"Sample",
    "defaultextension":".png",
    "title":"開くファイルを選択",
    "multiple":False
}

path=Open(**option).show()
print(path)

例えばこのようにすれば、ファイル選択画面が表示された時点で"C:/Users/Sample.png"が自動で選択されています。

また、typevariableにTkinterのウィジェット変数(StringVar)を指定すれば、filetypesを指定したり取得したりできます。

from tkinter.filedialog import Open
from tkinter import StringVar,_get_temp_root

root=_get_temp_root() #ここでは便宜上rootに一時的なものを入れていますが、実際に利用する場合はちゃんとしたものに設定してください

option = {
    "filetypes":[("PNG Image",".png"),("JPEG Image","*.jpg;*.jpeg"),("All Files",".*")],
    "typevariable":StringVar(root,value="JPEG Image"),
}

print(option["typevariable"].get()) #"JPEG Image"が指定されている

path=Open(root,**option).show()

print(option["typevariable"].get()) #"JPEG Image"以外を選択し、開くと値が変わる

print(path)

また、ウィジェット変数なのでTkinterの画面でも扱いやすいと思います。

以上です。