TkDND

tkdndはTkにDrag&Dropの機能を追加するためのTcl拡張パッケージです。
UNIX(X Window)とWindowsに対応し、国際化に対応したTcl8.1以上で動作します。
Drag&Dropプロトコルは、UNIXのXDNDプロトコルVersion4(KDE,GNOMEに対応)と、
WindowsのOLE Drag&Dropインタフェースに準拠しています。

コマンド形式

tkdndのコマンドは、Tkのbindコマンドの様なインタフェースになっています。

dnd bindsource widget type script
dnd clearsource widget

dnd bindtarget widget type event script
dnd cleartaget widget

dnd drag widget ?-action list? ?-description list? ?-cursorwindow widget? ?-callback script?

typeに指定できるタイプは以下の通りです。

タイプ説明
text/plain ASCII文字列に変換されます。
システムのencodingが使われ、ASCIIからUTF-8、UTF-8からASCIIのマッピングが行われます。
text/plain;charset=UTF-8 UTF-8文字列に変換されます。転送前と受信後に変換をしません。
text/uri-list ファイル名のリストとして扱われます。
システムのencodingが使われ、ASCIIからUTF-8、UTF-8からASCIIのマッピングが行われます。

bindsourceとbindtargetのスクリプト内では、以下のイベント予約語が使えます。

イベント予約語説明
%%1つの%に置換されます。
%ADrag&Drop操作のカレントアクション
%aDrag sourceによってサポートされるアクションリスト
%bDrag&Drop操作中にマウスボタンの押された状態
%DDropされたデータ(文字列)
%dDrag sourceによって提供された説明リスト
%m押されたキーボードの修飾キー
%TDrag&Drop操作のカレントタイプ
%Wイベントの発生したウィンドウ
%XマウスポインタのX座標(rootウィンドウ相対)
%xマウスポインタのX座標(イベントを受信したウィンドウ相対)
%YマウスポインタのY座標(rootウィンドウ相対)
%yマウスポインタのY座標(イベントを受信したウィンドウ相対)

eventに指定できるイベントは以下の通りです。

イベント説明
<DragEnter> Dargしているマウスポインタがwidgetに入った時に発生するイベントです。
<Drag> Dargしているマウスポインタがwidget上を移動した時に発生するイベントです。
<DragLeave> Dargしているマウスポインタがwidgetから出た時に発生するイベントです。
<Ask> Darg中にマウスボタンを離した時に発生するイベントです。
widgetがDropを許すかどうか調べるために使われます。
<Drop> DargしているマウスポインタをwidgetにDropした時に発生するイベントです。

サンプル1

文字列をDrag&Dropするサンプルです。Sourceの文字列をDragして、TargetにDropできます。
また、Dragに対応したアプリケーションから文字列をDragしてTargetにDropできます。

package require tkdnd

label .l1 -text "Source: "
entry .source
label .l2 -text "Target: "
entry .target
grid .l1 .source -sticky we
grid .l2 .target -sticky we

.source insert end {この文字列をDragできます}

# Source側
dnd bindsource .source {text/plain} {
    return [.source get]
}

bind .source <B1-Leave> {
    dnd drag %W
}

# Target側
dnd bindtarget .target {text/plain} <Drop> {
    .target insert end %D
}

Drag&Drop中

Dropできない場所にDrag中のマウスカーソルを持っていくとマウスカーソルが禁止マークになります。

サンプル2

エクスプローラ等のファイルマネージャからファイルをDragして
テキストWidgetにDropするサンプルです。

package require tkdnd

pack [text .text]

# Target側
dnd bindtarget .text text/uri-list <Drop> {
    .text insert end "%D\n"
}

Drag&Drop中

"%D"は、Dragした複数のファイル名がリスト形式で取得できることに注意してください。

注意事項

tkdndのバイナリ配布版は、Tcl8.3.3とTcl8.4以上のみの対応となっていて、
Tcl8.3.4やTcl8.2以下で使用するには、ソースの一部を修正する必要があります。
まだbeta版ですが、このあたりは改善の余地がありそうである。

最後に

tkdndは、国際化に対応しているので、日本語も問題なく扱えます。
動作も安定していて、完成度は高いという印象です。
ほんのわずかなコードの追加で、TkアプリケーションをDrag&Drop対応にできます。
Tcl8.4の標準パッケージにぜひ加えて欲しいTcl拡張パケージの1つです。

参考文献


tkdnd