Tkinter 拖放

Salman Mehmood 2023年1月30日
  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