Tkinterを使用してGUI開発ツールを作成します(47)Tkinterにファイルとディレクトリのドラッグアンドドロップ機能を実装します
。PythonTkinterは無料でオープンソースであるため、多くのプログラマーが多くの新しい機能モジュールを開発しています
。tkdndはtkのPythonラッパーです。拡張機能。tkdnd拡張機能は、ネイティブプラットフォーム固有のドラッグアンドドロップメカニズムへのインターフェイスを提供します。Unixでは、使用されるドラッグアンドドロッププロトコルはXDNDプロトコルバージョン5です(QtツールキットとKDEおよびGNOMEデスクトップでも使用されます)。Windowsでは、OLE2ドラッグアンドドロップインターフェイスを使用します。Macintoshでは、Cocoaのドラッグアンドドロップインターフェイスを使用します。
TkinterDnD2パッケージがインストールされたら、安全に続行できます。
from TkinterDnD2 import *
これにより、TkinterDnDクラスが追加されます。TkおよびTkinterDnD。グローバルネームスペースへのTixTkに加えて、次の定数:
PRIVATE、NONE、ASK、COPY、MOVE、LINK、REFUSE_DROP、
DND_TEXT、DND_FILES、DND_ALL、CF_UNICODETEXT、CF_TEXT、CF_HDROP、
FileGroupDescriptor、FileGroupDescriptorWをアプリケーションとしてドラッグアンドドロップします。使用可能
クラスの1つTkinterDnD.Tk()または(tix拡張機能を使用する必要がある場合)TkinterDnD.TixTk()が、通常のtkinter.Tk()ウィンドウの代わりにメインアプリケーションウィンドウとして使用されます。これにより、「Tk」ウィンドウとそのすべての子孫にドラッグアンドドロップ固有のメソッドが追加されます。
上記は元の作者によって紹介された翻訳です。簡単に言えば、root = tkinter.Tk()の代わりにroot = TkinterDnD.Tk()を使用してアプリケーションのメインウィンドウを作成し、このアプリケーションでtkinterまたはttkコントロールを使用します。tixを使用する場合は、root = tix.Tk()の代わりにroot = TkinterDnD.TixTk()を使用する必要があります。読者が理解できない場合は、私の著書「ゼロファンデーションで定量的投資システムを構築する-Pythonをツールとして使用する」の第8章にあるTkinterモジュールを読むことができます。https://item.jd.com/61567375505.html
第8章のTkinterモジュールは245
Tkinterの245個の8.1利用
Tkinterのコントロールのプロパティ8.2 250
8.3 Tkinterのメインウィンドウ260
8.4トップレベルのサブウインドウ263
8.5作成ウィンドウのメニューバー264
8.6ポップを作成します。アップメニュー2668.7コントロール
ジオメトリレイアウト管理方法2698.8Tkinter
共通コントロール2748.9Tkinter
イベントとバインディング
2998.10Ttkコントロール3048.11Tix
コントロール312
TkinterDnD2をインストールするには2つのステップがあります。
1. tkdnd2.8をダウンロードしてインストールします。
ダウンロードURLは次のとおりです
。https :
//sourceforge.net/projects/tkdnd/files/Windows%20Binaries/ダウンロードして解凍した後、フォルダーtkdnd2.8をコピーしてAnacondaに配置します。 /tcl/tcl8.6またはPython3.8 / tcl /tcl8.6。
2.TkinterDnD2作成
者のWebページhttp://tkinterdnd.sourceforge.net/をダウンロードしてインストールし
ます。ダウンロードして解凍した後、TkinterDnD2の場所を次のようにコピーします。Anaconda3
/ Lib / site-packages / TkinterDnD2
またはPython3.8 / Lib / site-packages / TkinterDnD2。
上記の2つの手順をインストールした後、tkinterでファイルのドラッグアンドドロップ機能を使用できます。
元のURLをダウンロードするのが簡単でない場合は、ネットワークディスクのtkdndディレクトリからダウンロードすることもできます。
https://pan.baidu.com/s/1jxSaB8JzOu6hNvFipqfGzQ
以下に、docやpyファイルなどのユーザーがドラッグアンドドロップしたファイルの種類とディレクトリに応じて、さまざまなアイコンが表示される簡単なデモプログラムを作成しました。
読者がTkinterを使用して、プログラムの例に基づいたWindowsと同様のファイルディレクトリの表示と管理を行うことは難しくありません。ソースコード全体はすぐ下にあります。
# -*- coding: utf-8 -*-
import os
from TkinterDnD2 import *
from tkinter import *
import PIL
#独狼荷蒲qq:2886002
#通通小白python量化群:524949939
#微信公众号:独狼股票分析
root = TkinterDnD.Tk()
root.withdraw()
root.title('TkinterDnD2 拖拽演示')
root.grid_rowconfigure(1, weight=1, minsize=250)
root.grid_columnconfigure(0, weight=1, minsize=300)
Label(root, text='拖拽文件或目录到这里:').grid(
row=0, column=0, padx=10, pady=5)
buttonbox = Frame(root)
buttonbox.grid(row=2, column=0, columnspan=2, pady=5)
Button(buttonbox, text='Quit', command=root.quit).pack(
side=LEFT, padx=5)
file_data = ('R0lGODlhGAAYAKIAANnZ2TMzMwAAAJmZmf///yH5BAEAAAAALAA'
'AAAAYABgAAAPACBi63IqgC4GiyxwogaAbKLrMgSKBoBoousyBogEACIGiyxwoKgGAECI'
'4uiyCExMTOACBosuNpDoAGCI4uiyCIkREOACBosutSDoAgSI4usyCIjQAGCi63Iw0ACE'
'oOLrMgiI0ABgoutyMNAAhKDi6zIIiNAAYKLrcjDQAISg4usyCIjQAGCi63Iw0AIGiiqP'
'LIyhCA4CBosvNSAMQKKo4ujyCIjQAGCi63Iw0AIGiy81IAxCBpMu9GAMAgKPL3QgJADs'
'=')
folder_data = ('R0lGODlhGAAYAKECAAAAAPD/gP///yH+EUNyZWF0ZWQgd2l0aCBHSU1QA'
'CH5BAEKAAIALAAAAAAYABgAAAJClI+pK+DvGINQKhCyztEavGmd5IQmYJXmhi7UC8frH'
'EL0Hdj4rO/n41v1giIgkWU8cpLK4dFJhAalvpj1is16toICADs=')
file_icon = PhotoImage(data=file_data)
#folder_icon = PhotoImage(data=folder_data)
folder_icon= PhotoImage(file="ico/folder.png")
word_icon= PhotoImage(file="ico/word.png")
py_icon= PhotoImage(file="ico/py.png")
canvas = Canvas(root, name='dnd_demo_canvas', bg='white', relief='sunken',
bd=1, highlightthickness=1, takefocus=True, width=600)
canvas.grid(row=1, column=0, padx=5, pady=5, sticky='news')
# store the filename associated with each canvas item in a dictionary
canvas.filenames = {
}
# store the next icon's x and y coordinates in a list
canvas.nextcoords = [50, 20]
# add a boolean flag to the canvas which can be used to disable
# files from the canvas being dropped on the canvas again
canvas.dragging = False
def add_file(filename):
icon = file_icon
file2,type2=os.path.splitext(filename)
if os.path.isdir(filename):
icon = folder_icon
elif type2=='.doc' or type2=='.docx':
icon = word_icon
elif type2=='.py' or type2=='.PY':
icon = py_icon
id1 = canvas.create_image(canvas.nextcoords[0], canvas.nextcoords[1],
image=icon, anchor='n', tags=('file',))
id2 = canvas.create_text(canvas.nextcoords[0], canvas.nextcoords[1] + 30,
text=os.path.basename(filename), anchor='n',
justify='center', width=90)
def select_item(ev):
canvas.select_from(id2, 0)
canvas.select_to(id2, 'end')
canvas.tag_bind(id1, '<ButtonPress-1>', select_item)
canvas.tag_bind(id2, '<ButtonPress-1>', select_item)
canvas.filenames[id1] = filename
canvas.filenames[id2] = filename
if canvas.nextcoords[0] > 450:
canvas.nextcoords = [50, canvas.nextcoords[1] + 80]
else:
canvas.nextcoords = [canvas.nextcoords[0] + 100, canvas.nextcoords[1]]
# drop methods
def drop_enter(event):
event.widget.focus_force()
print('Entering %s' % event.widget)
return event.action
def drop_position(event):
return event.action
def drop_leave(event):
print('Leaving %s' % event.widget)
return event.action
def drop(event):
if canvas.dragging:
# the canvas itself is the drag source
return REFUSE_DROP
if event.data:
files = canvas.tk.splitlist(event.data)
for f in files:
add_file(f)
return event.action
canvas.drop_target_register(DND_FILES)
canvas.dnd_bind('<<DropEnter>>', drop_enter)
canvas.dnd_bind('<<DropPosition>>', drop_position)
canvas.dnd_bind('<<DropLeave>>', drop_leave)
canvas.dnd_bind('<<Drop>>', drop)
# drag methods
def drag_init(event):
data = ()
sel = canvas.select_item()
if sel:
# in a decent application we should check here if the mouse
# actually hit an item, but for now we will stick with this
data = (canvas.filenames[sel],)
canvas.dragging = True
return ((ASK, COPY), (DND_FILES, DND_TEXT), data)
else:
# don't start a dnd-operation when nothing is selected; the
# return "break" here is only cosmetical, return "foobar" would
# probably do the same
return 'break'
def drag_end(event):
# reset the "dragging" flag to enable drops again
canvas.dragging = False
canvas.drag_source_register(1, DND_FILES)
canvas.dnd_bind('<<DragInitCmd>>', drag_init)
canvas.dnd_bind('<<DragEndCmd>>', drag_end)
root.update_idletasks()
root.deiconify()
root.mainloop()
プログラムの結果は次のとおりです
。私のブログをフォローし続けることを歓迎します。