2020年7月21日火曜日

Python3 tkinterでドラッグアンドドロップ

Pythonのtkinterでファイルをドロップしてそれを開くようなGUIをもったスクリプトを作るのは どうするのか調べてみた。 一つは、ctypes モジュールを用いて、WindowsのAPIを呼び出す方法がある。 もう一つは、TkDNDというTkの拡張ライブラリとそのPythonラッパーであるTkinterDnD2を用いる方法である。 ここでは、後者の方法を試してみた。 環境はWindows10、Python3.8.3、64bit環境である。

まずはこちらにいく。 TkinterDnD2のダウンロードができる。また、TkDND へのダウンロードリンクもある。 行うことは、Tkの拡張ライブラリであるTkDND2.8と、そのPythonラッパーであるTkinterDnD2をインストールすることである。

TkDNDのページへ行く。 64bit環境なら、 Windows Binaries/TkDND2.8の中にある tkdnd2.8-win32-x86_64.tar.gz をダウンロードする。

Python環境がインストールされているフォルダの中にtklというフォルダがある。 それぞれの環境ごとに場所が変わるので、 sys モジュールをインポートして、どこにpythonがインストールされているかを 調べてみるとよいだろう。 そのtklフォルダ中に、tkdnd2.8フォルダをそのまま配置する。

次に、こちらから TkinterDnD2-0.3.zipファイルをダウンロードする。 展開すると、TkinterDnD2フォルダといくつかのdemoファイルおよび 説明のhtmlファイルが得られる。 Pythonがインストールされているフォルダにある、 Lib\site-packagesの中にTkinterDnD2フォルダをそのまま配置すると完了である。

python からdemoを実行してみると動作を確認できる。 簡単なスクリプトは以下のものとなる。 エクスプローラからファイルを投げ込むと、そのファイルパスが表示される。 複数ファイルを投げ入れると、各ファイルパスがスペースで区切られたものとなる。

import sys
import os
import TkinterDnD2 as tkdnd
if sys.version > "3.0":
    import tkinter as tk
else:
    import Tkinter as tk

def drop_enter(event):
    event.widget.focus_force()
    return event.action

def drop_leave(event):
    event.widget._root().focus_force()
    return event.action

def drop_position(event):
    #print(event.x_root, event.y_root)
    return event.action

def drop(event):
    if event.data:
        print(event.data)
    return event.action

app = tkdnd.TkinterDnD.Tk()

app.drop_target_register(tkdnd.DND_FILES)
app.dnd_bind('<<DropEnter>>', drop_enter)
app.dnd_bind('<<DropLeave>>', drop_leave)
app.dnd_bind('<<DropPosition>>', drop_position)
app.dnd_bind('<<Drop>>', drop)

app.mainloop()

1 件のコメント:

匿名 さんのコメント...

"tkl"ではなく"tcl"だと思います