Tkinter 拖放

Salman Mehmood 2024年2月15日
  1. 在 Tkinter 中拖放文件
  2. 在 Tkinter 中下载并设置拖放的基本包
  3. 在 Tkinter 中使用 TkinterDnD2 库拖放文件
  4. 使用 TkinterDnD2 库在 Tkinter 的列表框中拖放文件和文件夹
  5. 在 Tkinter 中使用 TkinterDnD2 库拖放图像
Tkinter 拖放

本教程将演示如何使用 Tkinter GUI 上的 TkinterDnD2 库拖放对象。TkinterDnD2 是一个帮助拖放对象的外部工具。

在 Tkinter 中拖放文件

按住左键的同时拖放有助于移动文件、文件夹和对象。可以根据官方文档将对象拖动到 x 轴或 y 轴以允许拖动对象。

我们需要一个回调方法来创建一个事件。该方法应该调用 Tkdnd.dnd_start (source, event),其中 source 是要拖动的对象,event 是请求的调用。

我们尝试过这种方式,但它不起作用。所以我们找到了一种方法来做到这一点。

拖放涉及三个任务。

  1. 你必须按下鼠标按钮。
  2. 你必须移动鼠标。
  3. 你必须松开鼠标按钮。

所有这些活动都可以通过设置一个事件来完成。我们将使用鼠标按钮事件来拖放一个项目。

在继续之前,让我们安装拖放所需的基本包。

在 Tkinter 中下载并设置拖放的基本包

要下载 tkdnd2.8 外部库,请点击这里。要下载 TkinterDnD2 外部库,请点击这里

提取这两个文件夹并找到 Python 的安装位置。

将提取的 tkdnd2.8 文件夹移动到放置在 Python 文件夹中的 tcl 文件夹中。在我们的例子中,tcl 文件夹位于此处 C:\python\tcl

将提取的 TkinterDnD2 文件夹移动到 site-packages 文件夹。

在我们的例子中,site-packages 文件夹位于此处 C:\python\Lib\site-packages

完成这些步骤后,我们就可以开发应用程序了。

如果你在设置时遇到问题,可以点击此链接

在 Tkinter 中使用 TkinterDnD2 库拖放文件

在本例中,我们将一个文件拖放到放置在框架中的 Text() 组件中。该程序只能读取文本文件,但你可以使用其他扩展名。

from tkinter import *
from TkinterDnD2 import *


def DisplayText(event):
    # delete entire existing content
    textbox.delete("1.0", "end")
    # check the file holds txt extension
    if event.data.endswith(".txt"):
        with open(event.data, "r") as f:
            # getting content in a variable
            for text_line in f:
                text_line = text_line.strip()
                textbox.insert("end", f"{text_line}\n")


win = TkinterDnD.Tk()
win.title("Delftstack")
win.geometry("500x400")
win.config(bg="gold")

frame = Frame(win)
frame.pack()

textbox = Text(frame, height=22, width=50)
textbox.pack(side=LEFT)
textbox.drop_target_register(DND_FILES)
textbox.dnd_bind("<<Drop>>", DisplayText)

scrolbar = Scrollbar(frame, orient=VERTICAL)
scrolbar.pack(side=RIGHT, fill=Y)

textbox.configure(yscrollcommand=scrolbar.set)
scrolbar.config(command=textbox.yview)

win.mainloop()

我们使用 TkinterDnD.Tk() 创建了 TK() 类的对象。在此之后,我们创建了一个包含文本框的框架。我们可以使用 Text() 组件声明一个文本框。

drop_target_register(DND_FILES) 方法在文本框中腾出空间来接受拖动的文件。

dnd_bind('<<Drop>>', DisplayText) 方法绑定事件和函数;第一个参数是一个事件,第二个是一个函数。

当我们拖动文件并在文本框中释放它时,将调用 DisplayText() 函数。该功能将从文本框中删除整个现有内容,检查扩展名是否为 .txt

在文本组件中拖放

使用 TkinterDnD2 库在 Tkinter 的列表框中拖放文件和文件夹

在这段代码中,我们创建了一个 Listbox() 组件。此组件显示多个项目并允许你选择多个项目。

在我们的例子中,Listbox() 组件使用拖放保存多个位置。

from tkinter import *
from TkinterDnD2 import *


def path_listbox(event):
    listbox.insert("end", event.data)


window = TkinterDnD.Tk()
window.title("Delftstack")
window.geometry("400x300")
window.config(bg="gold")
frame = Frame(window)
frame.pack()

listbox = Listbox(
    frame,
    width=50,
    height=15,
    selectmode=SINGLE,
)
listbox.pack(fill=X, side=LEFT)
listbox.drop_target_register(DND_FILES)
listbox.dnd_bind("<<Drop>>", path_listbox)

scrolbar = Scrollbar(frame, orient=VERTICAL)
scrolbar.pack(side=RIGHT, fill=Y)
# displays the content in listbox
listbox.configure(yscrollcommand=scrolbar.set)
# view the content vertically using scrollbar
scrolbar.config(command=listbox.yview)

window.mainloop()

path_listbox() 函数将在拖动对象时被调用。insert() 方法将帮助在此函数的 Listbox 中插入数据。

在列表框中拖放

在 Tkinter 中使用 TkinterDnD2 库拖放图像

我们使用 TkinterDnD2 库来拖放图像。我们使用 StringVar() 类创建了一个字符串对象,并将其设置在此代码的 Entry() 组件上。

当文件被拖到入口组件上时,就会调用 DropImage() 函数。此功能有助于获取文件路径并显示图像。

from tkinter import *
from TkinterDnD2 import *
from PIL import ImageTk, Image


def DropImage(event):
    testvariable.set(event.data)
    # get the value from string variable
    window.file_name = testvariable.get()
    # takes path using dragged file
    image_path = Image.open(str(window.file_name))
    # resize image
    reside_image = image_path.resize((300, 205), Image.ANTIALIAS)
    # displays an image
    window.image = ImageTk.PhotoImage(reside_image)
    image_label = Label(labelframe, image=window.image).pack()


window = TkinterDnD.Tk()
window.title("Delftstack")
window.geometry("400x300")
window.config(bg="gold")

testvariable = StringVar()
textlabel = Label(window, text="drop the file here", bg="#fcba03")
textlabel.pack(anchor=NW, padx=10)
entrybox = Entry(window, textvar=testvariable, width=80)
entrybox.pack(fill=X, padx=10)
entrybox.drop_target_register(DND_FILES)
entrybox.dnd_bind("<<Drop>>", DropImage)

labelframe = LabelFrame(window, bg="gold")

labelframe.pack(fill=BOTH, expand=True, padx=9, pady=9)

window.mainloop()

输出:

拖放图像

点击这里阅读官方文档。

作者: Salman Mehmood
Salman Mehmood avatar Salman Mehmood avatar

Hello! I am Salman Bin Mehmood(Baum), a software developer and I help organizations, address complex problems. My expertise lies within back-end, data science and machine learning. I am a lifelong learner, currently working on metaverse, and enrolled in a course building an AI application with python. I love solving problems and developing bug-free software for people. I write content related to python and hot Technologies.

LinkedIn