我对Python很新.我正在尝试将文件名(包含完整路径)输入到TKinter条目小部件.由于文件名的路径可能很长,我希望能够直接从Windows资源管理器拖放文件.在Perl中我看到了以下内容:
use Tk::DropSite;
.
.
my $mw = new MainWindow;
$top = $mw->Toplevel;
$label_entry = $top->Entry(-width => '45',. -background => 'ivory2')->pack();
$label_entry->DropSite(-dropcommand => \&drop,-droptypes => 'Win32',);
Run Code Online (Sandbox Code Playgroud)
我在Python中使用TKinter可以做些什么吗?
mmg*_*mgp 15
Tk没有任何命令来处理它,并且Python不包含任何额外的Tk扩展来执行拖放交互应用程序,因此您需要扩展来执行操作.Tkdnd(http://sourceforge.net/projects/tkdnd上的Tk扩展,而不是Tkdnd.py模块)适合我.要从Python中使用它,需要一个包装器.快速搜索一个,似乎http://mail.python.org/pipermail/tkinter-discuss/2005-July/000476.html包含这样的代码.我做了另一个,因为我不喜欢那个.我的包装器的问题在于它是高度未经测试的,事实上我只使用了这个功能bindtarget
并且只用了10秒左右.
使用下面的包装器,您可以创建一些小部件并宣布它支持接收拖动的文件.这是一个例子:
# The next two lines are not necessary if you installed TkDnd
# in a proper place.
import os
os.environ['TKDND_LIBRARY'] = DIRECTORYTOTHETKDNDBINARY
import Tkinter
from untested_tkdnd_wrapper import TkDND
root = Tkinter.Tk()
dnd = TkDND(root)
entry = Tkinter.Entry()
entry.pack()
def handle(event):
event.widget.insert(0, event.data)
dnd.bindtarget(entry, handle, 'text/uri-list')
root.mainloop()
Run Code Online (Sandbox Code Playgroud)
以下是代码untested_tkdnd_wrapper.py
:
import os
import Tkinter
def _load_tkdnd(master):
tkdndlib = os.environ.get('TKDND_LIBRARY')
if tkdndlib:
master.tk.eval('global auto_path; lappend auto_path {%s}' % tkdndlib)
master.tk.eval('package require tkdnd')
master._tkdnd_loaded = True
class TkDND(object):
def __init__(self, master):
if not getattr(master, '_tkdnd_loaded', False):
_load_tkdnd(master)
self.master = master
self.tk = master.tk
# Available pre-defined values for the 'dndtype' parameter:
# text/plain
# text/plain;charset=UTF-8
# text/uri-list
def bindtarget(self, window, callback, dndtype, event='<Drop>', priority=50):
cmd = self._prepare_tkdnd_func(callback)
return self.tk.call('dnd', 'bindtarget', window, dndtype, event,
cmd, priority)
def bindtarget_query(self, window, dndtype=None, event='<Drop>'):
return self.tk.call('dnd', 'bindtarget', window, dndtype, event)
def cleartarget(self, window):
self.tk.call('dnd', 'cleartarget', window)
def bindsource(self, window, callback, dndtype, priority=50):
cmd = self._prepare_tkdnd_func(callback)
self.tk.call('dnd', 'bindsource', window, dndtype, cmd, priority)
def bindsource_query(self, window, dndtype=None):
return self.tk.call('dnd', 'bindsource', window, dndtype)
def clearsource(self, window):
self.tk.call('dnd', 'clearsource', window)
def drag(self, window, actions=None, descriptions=None,
cursorwin=None, callback=None):
cmd = None
if cursorwin is not None:
if callback is not None:
cmd = self._prepare_tkdnd_func(callback)
self.tk.call('dnd', 'drag', window, actions, descriptions,
cursorwin, cmd)
_subst_format = ('%A', '%a', '%b', '%D', '%d', '%m', '%T',
'%W', '%X', '%Y', '%x', '%y')
_subst_format_str = " ".join(_subst_format)
def _prepare_tkdnd_func(self, callback):
funcid = self.master.register(callback, self._dndsubstitute)
cmd = ('%s %s' % (funcid, self._subst_format_str))
return cmd
def _dndsubstitute(self, *args):
if len(args) != len(self._subst_format):
return args
def try_int(x):
x = str(x)
try:
return int(x)
except ValueError:
return x
A, a, b, D, d, m, T, W, X, Y, x, y = args
event = Tkinter.Event()
event.action = A # Current action of the drag and drop operation.
event.action_list = a # Action list supported by the drag source.
event.mouse_button = b # Mouse button pressed during the drag and drop.
event.data = D # The data that has been dropped.
event.descr = d # The list of descriptions.
event.modifier = m # The list of modifier keyboard keys pressed.
event.dndtype = T
event.widget = self.master.nametowidget(W)
event.x_root = X # Mouse pointer x coord, relative to the root win.
event.y_root = Y
event.x = x # Mouse pointer x coord, relative to the widget.
event.y = y
event.action_list = str(event.action_list).split()
for name in ('mouse_button', 'x', 'y', 'x_root', 'y_root'):
setattr(event, name, try_int(getattr(event, name)))
return (event, )
Run Code Online (Sandbox Code Playgroud)
与Tkdnd一起,您将找到一个tkdnd.tcl
比它提供的自己的C扩展更高级别的程序.我没有包装这个更高级别的代码,但是在Python中复制它比使用这个更低级别的包装器更有趣.
Eli*_*ski 15
您现在可以简单地使用tkinterdnd2。我已经分叉了它,构建了它,并将其上传到 pypi,这样你就可以简单地pip install tkinterdnd2
. 使用示例在这里
或者如果你太懒了,这里有一个简单的例子:
import tkinter as tk
from tkinterdnd2 import DND_FILES, TkinterDnD
root = TkinterDnD.Tk() # notice - use this instead of tk.Tk()
lb = tk.Listbox(root)
lb.insert(1, "drag files to here")
# register the listbox as a drop target
lb.drop_target_register(DND_FILES)
lb.dnd_bind('<<Drop>>', lambda e: lb.insert(tk.END, e.data))
lb.pack()
root.mainloop()
Run Code Online (Sandbox Code Playgroud)
(顺便说一句,我使用列表框而不是条目,但它的工作原理完全相同)
自从这个问题最初发布以来,事情已经取得了进展,并且在SourceForge.net上可以获得tkdnd2.8(Tcl扩展)和TkinterDnD2(tkdnd2.8的Python包装器).
这里是最简单的示例代码,可以完全按照您的要求进行操作.
import Tkinter
from TkinterDnD2 import *
def drop(event):
entry_sv.set(event.data)
root = TkinterDnD.Tk()
entry_sv = Tkinter.StringVar()
entry = Tkinter.Entry(root, textvar=entry_sv, width=80)
entry.pack(fill=Tkinter.X)
entry.drop_target_register(DND_FILES)
entry.dnd_bind('<<Drop>>', drop)
root.mainloop()
Run Code Online (Sandbox Code Playgroud)
您可以在OSX上查看如何在OSX上安装和使用TkDnD与Python 2.7 Tkinter,以获取适用于Python 2.7和3.6的Windows和Mac的下载和安装信息.
归档时间: |
|
查看次数: |
22896 次 |
最近记录: |