mieki256's diary



2021/12/10(金) [n年前の日記]

#1 [python] tkinterdnd2を試用

Python + tkinter を使うと、ちょっとしたGUIアプリを作ることができるのだけど、tkinter の標準状態ではドラッグアンドロップ(DnD、D&D)を受け付ける機能が無いそうで。例えば、Windows のエクスプローラ等から tkinter のウインドウにファイルアイコンをD&Dしてもファイルパスを取得することができない。

そのあたりどうにかできないのかなとググってみたら、tkinterdnd2 というライブラリをインストールするとできるようになると知ったので、手元で少し試してみた。

環境は Windows10 x64 21H1 + Python 3.9.9 x64。

_【Python】tkinter:ファイルのドラッグアンドドロップ(パス取得、画像表示) | OFFICE54
_Eliav2/tkinterdnd2: Tkinter native drag and drop support for windows, unix and Mac OSX.
_tkinterdnd2 - PyPI

インストール。 :

昔は、tkinterdnd2 を使うためには、TkDND というTkの拡張パッケージを別途インストールする必要があったのだけど。

_mieki256's diary - Python + Tkinter でドラッグアンドドロップ

今現在は、tkinterdnd2 を pip でインストーするだけで使えるようになる模様。github上のファイル群を眺めたら *.dll も並んでいたので、必要な *.dll も pip で入れてくれるのだろう。

pip install tkinterdnd2

今回は tkinterdnd2 0.3.0 がインストールされた。

動作サンプル。 :

解説記事を参考にしつつ、tk.Entry(InputBox相当、入力フィールド) にファイルをD&Dすれば、ファイルパスが入るスクリプトを書いてみた。

_02_tkintrdnd2_sample2.py
import tkinter as tk
from tkinter import ttk
from tkinterdnd2 import *

def drop(event):
    print(event.data)
    text.set(event.data)

root = TkinterDnD.Tk()
root.geometry("640x100")
root.title("Drag and drop with Entry")

text = tk.StringVar()
text.set("Please file drop")

entry = ttk.Entry(root, textvariable=text)
entry.pack(expand=True, fill=tk.X, padx=16, pady=8)

entry.drop_target_register(DND_FILES)
entry.dnd_bind("<<Drop>>", drop)

root.mainloop()

02_tkintrdnd2_sample2_py_ss.gif

エクスプローラからファイルをD&Dして、ファイルパスを取得できた。

ちなみに、巷の解説記事ではスクリプト内で .dnd_bind("<>", drop) と記述されていたけど、現行バージョンではその記述だと動かなった。.dnd_bind("<<Drop>>", drop) にしてみたら動いてくれた。

windnd を試用。 :

ググっていたら、windnd というライブラリをインストールすることでもD&Dが使えるようになると知った。

_windnd - PyPI
_cilame/windnd
_Arrastrar y soltar archivo de implementacion de Python + tkinter

github上のソースを眺めてみたけれど、Windows API を使ってD&Dを使えるようにしているっぽい。tkinterdnd2 の場合は動作させるために複数の *.dll をインストールするけれど、windnd は .pyファイル一つで実現している模様。

もちろん、Windows API を使っているから Windows上でしか使えないというデメリットはあるけれど、Windows上でしか使わないスクリプトであれば問題にはならないはず。

試しにインストールしてサンプルを書いてみた。

pip install windnd

_01_windnd_sample1.py
import tkinter as tk
import windnd

def dragged_files(files):
    s = ";".join((item.decode("utf-8") for item in files))
    text.set(s)
    print(text.get())

root = tk.Tk()

text = tk.StringVar()
text.set("Please file drop")

entry = tk.Entry(root, textvariable=text, width=80)
entry.pack(expand=True, fill=tk.X, padx=16, pady=8)

windnd.hook_dropfiles(root, func=dragged_files)

root.mainloop()

01_windnd_sample1_py_ss.gif

こちらも動いてくれた。

以上です。

過去ログ表示

Prev - 2021/12 - Next
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31

カテゴリで表示

検索機能は Namazu for hns で提供されています。(詳細指定/ヘルプ


注意: 現在使用の日記自動生成システムは Version 2.19.6 です。
公開されている日記自動生成システムは Version 2.19.5 です。

Powered by hns-2.19.6, HyperNikkiSystem Project