Use Tkinter to create GUI development tools (47) to realize the drag and drop function of files and directories in Tkinter

Use Tkinter to create GUI development tools (47) Implement the drag and drop function of files and directories in Tkinter.
Python Tkinter is free and open source, so many programmers have developed many new functional modules on it.
tkdnd is a Python wrapper for tk extensions. The tkdnd extension provides an interface to the native platform-specific drag and drop mechanism. Under Unix, the drag-and-drop protocol used is XDND protocol version 5 (also used by the Qt toolkit and KDE and GNOME desktops). Under Windows, use the OLE2 drag and drop interface. Under Macintosh, use Cocoa drag and drop interface.
Once the TkinterDnD2 package is installed, you can safely proceed:

 from TkinterDnD2 import *

This will add the TkinterDnD class. Tk and TkinterDnD. TixTk to the global namespace, plus the following constants:
PRIVATE, NONE, ASK, COPY, MOVE, LINK, REFUSE_DROP,
DND_TEXT, DND_FILES, DND_ALL, CF_UNICODETEXT, CF_TEXT, CF_HDROP,
FileGroupDescriptor, FileGroupDescriptor. One of the enabled
classes TkinterDnD.Tk() or (if the tix extension should be used) TkinterDnD.TixTk() is used as the main application window instead of the regular tkinter.Tk() window. This will add drag and drop specific methods to the "Tk" window and all its descendants.

The above is the translation introduced by the original author. Simply put, use root=TkinterDnD.Tk() instead of root=tkinter.Tk() to create the main window of the application, and use tkinter or ttk controls in this application. If you want to use tix, you need to use root=TkinterDnD.TixTk() instead of root=tix.Tk(). If readers do not understand, you can read the Tkinter module in Chapter 8 of my book "Building a Quantitative Investment System with Zero Foundation-Using Python as a Tool". https://item.jd.com/61567375505.html
Chapter 8 Tkinter Module 245
8.1 Use of Tkinter 245
8.2 Properties of Tkinter Control 250
8.3 Tkinter Main Window 260
8.4 Toplevel Sub-Window 263
8.5 Create Window Menu Bar 264
8.6 Create Pop-up Menu 266
8.7 Control Geometry Layout Management Method 269
8.8 Tkinter Common Controls 274
8.9 Tkinter Events and Binding 299
8.10 Ttk Controls 304
8.11 Tix Controls 312

There are two steps to install TkinterDnD2.
1. Download and install tkdnd2.8. The
download URL is as follows:
https://sourceforge.net/projects/tkdnd/files/Windows%20Binaries/ After
downloading and unpacking, copy the folder tkdnd2.8 and place it in Anaconda/tcl/tcl8.6 Or Python3.8/tcl/tcl8.6.
2. Download and install TkinterDnD2
author webpage http://tkinterdnd.sourceforge.net/ After
downloading and unpacking, copy the TkinterDnD2 location as follows:
Anaconda3/Lib/site-packages/TkinterDnD2
or Python3.8 /Lib/site-packages/TkinterDnD2.

After the above two steps are installed, you can use the file drag and drop function in tkinter.
If the original URL is not easy to download, you can also download it from the tkdnd directory of my network disk.
https://pan.baidu.com/s/1jxSaB8JzOu6hNvFipqfGzQ

Below I made a simple demo program, according to the file type dragged and dropped by the user, such as doc or py file, and directory, different icons are displayed.
It is not difficult for readers to use Tkinter to do a file directory display and manager similar to windows based on program examples. The entire source code is given directly below.

# -*- 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()

The results of the program are as follows:
Insert picture description here
Welcome to continue to follow my blog.

Surpassing myself is every step of me! My progress is your progress!

Guess you like

Origin blog.csdn.net/hepu8/article/details/108181230