Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #44493 > unrolled thread

Drag and drop in Windows

Started byRobert Flintham <Robert.Flintham@uhb.nhs.uk>
First post2013-04-29 11:25 +0100
Last post2013-05-01 10:25 +0200
Articles 8 — 3 participants

Back to article view | Back to comp.lang.python


Contents

  Drag and drop in Windows Robert Flintham <Robert.Flintham@uhb.nhs.uk> - 2013-04-29 11:25 +0100
    Re: Drag and drop in Windows Christian Gollwitzer <auriocus@gmx.de> - 2013-04-29 22:38 +0200
    RE: Drag and drop in Windows Robert Flintham <Robert.Flintham@uhb.nhs.uk> - 2013-04-30 09:39 +0100
      Re: Drag and drop in Windows Christian Gollwitzer <auriocus@gmx.de> - 2013-04-30 14:08 +0200
    Re: Drag and drop in Windows Kevin Walzer <kw@codebykevin.com> - 2013-04-30 10:33 -0400
    Re: Drag and drop in Windows Kevin Walzer <kw@codebykevin.com> - 2013-04-30 19:09 -0400
    RE: Drag and drop in Windows Robert Flintham <Robert.Flintham@uhb.nhs.uk> - 2013-05-01 09:06 +0100
      Re: Drag and drop in Windows Christian Gollwitzer <auriocus@gmx.de> - 2013-05-01 10:25 +0200

#44493 — Drag and drop in Windows

FromRobert Flintham <Robert.Flintham@uhb.nhs.uk>
Date2013-04-29 11:25 +0100
SubjectDrag and drop in Windows
Message-ID<mailman.1148.1367231567.3114.python-list@python.org>

[Multipart message — attachments visible in raw view] — view raw

Hello all,

Sorry to post such a generic question, but after searching the interwebs I'm not really any wiser about how to start with this.

I'm currently on:
Windows XP
Python 2.7

I'm trying to create a small window in Python 2.7, that when you drop a file onto it from Windows explorer returns the file's path so that I can then go on to open the file and do whatever with it.  I was planning on using Tkinter because that's what I've used before for GUI's, but I can be swayed from this if needs be.

I've found this (TkDND):
http://wiki.tcl.tk/2768

But I don't know how to implement this in Python.  The Windows binary for it comes as a set of ".tcl" files and a single ".dll" file.

The two options I've stumbled across seem to be

1.  a Python wrapper for the DLL (I think to wrap C code??), which can then be imported like you'd import a Python package

2.  direct implementation of the Tcl file [tk.eval('source ...')], but I don't reallu understand what's going on with this - can you only execute a "main" bit of Tcl files rather than implementing individual functions?

Any input (however minimal) is definitely appreciated!  I've included what I think are probably the relevant functions from the Tcl files at the bottom of the email, but I don't really understand the nuts and bolts of the code.

All the best,
Rob

[From "tkdnd.tcl"...]

# ----------------------------------------------------------------------------
#  Command tkdnd::drag_source
# ----------------------------------------------------------------------------
proc tkdnd::drag_source { mode path { types {} } { event 1 } } {
  set tags [bindtags $path]
  set idx  [lsearch $tags "TkDND_Drag*"]
  switch -- $mode {
    register {
      if { $idx != -1 } {
        bindtags $path [lreplace $tags $idx $idx TkDND_Drag$event]
      } else {
        bindtags $path [concat $tags TkDND_Drag$event]
      }
      set types [platform_specific_types $types]
      set old_types [bind $path <<DragSourceTypes>>]
      foreach type $types {
        if {[lsearch $old_types $type] < 0} {lappend old_types $type}
      }
      bind $path <<DragSourceTypes>> $old_types
    }
    unregister {
      if { $idx != -1 } {
        bindtags $path [lreplace $tags $idx $idx]
      }
    }
  }
};# tkdnd::drag_source


[From "tkdnd_windows.tcl"...]

# ----------------------------------------------------------------------------
#  Command olednd::_GetDragSource
# ----------------------------------------------------------------------------
proc olednd::_GetDragSource {  } {
  variable _drag_source
  return $_drag_source
};# olednd::_GetDragSource
DISCLAIMER:
This email and any attachments hereto contains proprietary information, some or all of which may be confidential or legally privileged. It is for the exclusive use of the intended recipient(s) only. If an addressing or transmission error has misdirected this e-mail and you are not the intended recipient(s), please notify the author by replying to this e-mail. If you are not the intended recipient you must not use, disclose, distribute, copy, print, or rely on this e-mail or any attachments, as this may be unlawful.

[toc] | [next] | [standalone]


#44522

FromChristian Gollwitzer <auriocus@gmx.de>
Date2013-04-29 22:38 +0200
Message-ID<klmlhu$amd$1@dont-email.me>
In reply to#44493
Hi Robert,

Am 29.04.13 12:25, schrieb Robert Flintham:
> I’ve found this (TkDND):
>
> http://wiki.tcl.tk/2768
 > But I don’t know how to implement this in Python.  The Windows binary
 > for it comes as a set of “.tcl” files and a single “.dll” file.
 > 2.direct implementation of the Tcl file [tk.eval(‘source …’)], but I
 > don’t reallu understand what’s going on with this – can you only execute
 > a “main” bit of Tcl files rather than implementing individual functions?

I can only comment on the Tcl side, since I'm not an expert in the 
Tkinter coupling mechanism. TkDND is indeed the way to go if you want 
native drag'n'drop support. The first step would indeed be to load the 
package into the Tcl interpreter. You need to:

1) Create a folder for the packages, put the files in a subfolder
Typically, this is something like lib/tkdnd, and at that level there 
must be the "pkgIndex.tcl" file
2) Append the lib/ folder to the auto path
tk.eval('lappend auto_path {mypath/lib}')
(the braces are Tcl's quoting mechanism)
3) load the package
tk.eval('package require tkdnd')

Then, you need to "register the target", i.e. declare a widget that it 
accepts files. Here, you need the Tk path name of the widget, which is 
retrieved by __str__:

tk.eval('tkdnd::drop_target register ' + yourwidget +' *')

Then, if you drop something, the widget recieves a virtual event 
<<Drop:DND_Files>> . Now this is tricky, I don't know how to bind to 
that event. Following the tutorial for Tcl on http://wiki.tcl.tk/36708, 
I suppose something like

	yourwidget.bind("<<Drop::DND_Files>>", filesdropped)

should in principle work, but how to get the data out of it? It is 
stuffed into the %D bind substitution. Usual events store the MouseWheel 
distance in this field; so maybe you can get it from the field 
event.delta. I can't test it now, but I am a bit skeptical whether this 
works with the guts of TkInter. If not, you'd need to do some more 
forwarding from the Tcl side.

	Christian

[toc] | [prev] | [next] | [standalone]


#44533

FromRobert Flintham <Robert.Flintham@uhb.nhs.uk>
Date2013-04-30 09:39 +0100
Message-ID<mailman.1173.1367311190.3114.python-list@python.org>
In reply to#44493
Thanks Christian.

I've tried the following code:
################
import Tkinter

root = Tkinter.Tk()
root.title("DICOM Opener")
root.tk.eval('lappend auto_path {K:/Python27/Lib/site-packages/tkdnd2.6}')
root.tk.eval('package require tkdnd')
################

But I get the following traceback:
################
Traceback (most recent call last):
  File "K:\eclipse\plugins\org.python.pydev_2.7.1.2012100913\pysrc\pydevd.py", line 1397, in <module>
    debugger.run(setup['file'], None, None)
  File "K:\eclipse\plugins\org.python.pydev_2.7.1.2012100913\pysrc\pydevd.py", line 1090, in run
    pydev_imports.execfile(file, globals, locals) #execute the script
  File "K:\PROGRAMMING\mripy\dicom_opener.py", line 7, in <module>
    root.tk.eval('package require tkdnd')
_tkinter.TclError: couldn't load library "K:/Python27/Lib/tkdnd2.6/tkdnd26.dll": invalid argument
################

Is "invalid argument" as generic as it sounds, or does it mean something specific in this case?  Is Tcl expecting an additional argument in the 'package require' line?

I assume the append auto path line is correct as it seems to have found the DLL (presumably from pkgIndex.tcl).

Apologies for any disclaimers that pad out this message - it's a work email account and they get added after I hit "send".

All the best,
Rob

-----Original Message-----
From: Python-list [mailto:python-list-bounces+robert.flintham=uhb.nhs.uk@python.org] On Behalf Of Christian Gollwitzer
Sent: 29 April 2013 21:38
To: python-list@python.org
Subject: Re: Drag and drop in Windows

Hi Robert,

Am 29.04.13 12:25, schrieb Robert Flintham:
> I've found this (TkDND):
>
> http://wiki.tcl.tk/2768
 > But I don't know how to implement this in Python.  The Windows binary  > for it comes as a set of ".tcl" files and a single ".dll" file.
 > 2.direct implementation of the Tcl file [tk.eval('source ...')], but I  > don't reallu understand what's going on with this - can you only execute  > a "main" bit of Tcl files rather than implementing individual functions?

I can only comment on the Tcl side, since I'm not an expert in the Tkinter coupling mechanism. TkDND is indeed the way to go if you want native drag'n'drop support. The first step would indeed be to load the package into the Tcl interpreter. You need to:

1) Create a folder for the packages, put the files in a subfolder Typically, this is something like lib/tkdnd, and at that level there must be the "pkgIndex.tcl" file
2) Append the lib/ folder to the auto path tk.eval('lappend auto_path {mypath/lib}') (the braces are Tcl's quoting mechanism)
3) load the package
tk.eval('package require tkdnd')

Then, you need to "register the target", i.e. declare a widget that it accepts files. Here, you need the Tk path name of the widget, which is retrieved by __str__:

tk.eval('tkdnd::drop_target register ' + yourwidget +' *')

Then, if you drop something, the widget recieves a virtual event <<Drop:DND_Files>> . Now this is tricky, I don't know how to bind to that event. Following the tutorial for Tcl on http://wiki.tcl.tk/36708, I suppose something like

	yourwidget.bind("<<Drop::DND_Files>>", filesdropped)

should in principle work, but how to get the data out of it? It is stuffed into the %D bind substitution. Usual events store the MouseWheel distance in this field; so maybe you can get it from the field event.delta. I can't test it now, but I am a bit skeptical whether this works with the guts of TkInter. If not, you'd need to do some more forwarding from the Tcl side.

	Christian
--
http://mail.python.org/mailman/listinfo/python-list

DISCLAIMER:
This email and any attachments hereto contains proprietary information, some or all of which may be confidential or legally privileged. It is for the exclusive use of the intended recipient(s) only. If an addressing or transmission error has misdirected this e-mail and you are not the intended recipient(s), please notify the author by replying to this e-mail. If you are not the intended recipient you must not use, disclose, distribute, copy, print, or rely on this e-mail or any attachments, as this may be unlawful.

[toc] | [prev] | [next] | [standalone]


#44536

FromChristian Gollwitzer <auriocus@gmx.de>
Date2013-04-30 14:08 +0200
Message-ID<kloc0t$v95$1@dont-email.me>
In reply to#44533
Hi Robert,

Am 30.04.13 10:39, schrieb Robert Flintham:
> Thanks Christian.
>
> I've tried the following code: ################ import Tkinter
>
> root = Tkinter.Tk() root.title("DICOM Opener") root.tk.eval('lappend
> auto_path {K:/Python27/Lib/site-packages/tkdnd2.6}')
> root.tk.eval('package require tkdnd') ################
>
> But I get the following traceback: ################
> _tkinter.TclError: couldn't load library
> "K:/Python27/Lib/tkdnd2.6/tkdnd26.dll": invalid argument
> ################
>
> Is "invalid argument" as generic as it sounds, or does it mean
> something specific in this case?  Is Tcl expecting an additional
> argument in the 'package require' line?
>
> I assume the append auto path line is correct as it seems to have
> found the DLL (presumably from pkgIndex.tcl).

Yes, actually this means the the "package require" in principle succeeds 
to perfrom the necessary steps. The EINVALID on Windows in most cases 
menas, that the DLL has the wrong word size. I.e., you run Tcl in 32 bit 
and try to load tkdnd-DLL with 64 bit or vice versa. You can get the 
bitsize from Tcl with

	"set tcl_platform(pointerSize)"
If it tells 4, Tcl runs on 32bit, if 8, it runs on 64bit.

The second problem might be, that the tkdnd.dll depends on some other 
DLL which can't be found by Windows. To debug this, install a tool like 
"Dependency walker". I don't use Windows anymore, so my memory might be 
diffuse.

	Christian

[toc] | [prev] | [next] | [standalone]


#44543

FromKevin Walzer <kw@codebykevin.com>
Date2013-04-30 10:33 -0400
Message-ID<klokgs$ec7$1@dont-email.me>
In reply to#44493
On 4/29/13 6:25 AM, Robert Flintham wrote:

>
> I’ve found this (TkDND):
>
> http://wiki.tcl.tk/2768
>

Michael Lange has written a nice Python wrapper for TkDND. His site is 
offline at the moment, but I found the source files on my system and 
have wrapped them up here:

http://www.codebykevin.com/TkinterDnD2-0.zip

Hope this helps,
Kevin

-- 
Kevin Walzer
Code by Kevin/Mobile Code by Kevin
http://www.codebykevin.com
http://www.wtmobilesoftware.com

[toc] | [prev] | [next] | [standalone]


#44573

FromKevin Walzer <kw@codebykevin.com>
Date2013-04-30 19:09 -0400
Message-ID<klpip7$8ld$1@dont-email.me>
In reply to#44493
Official link:

http://tkinterdnd.sourceforge.net

[toc] | [prev] | [next] | [standalone]


#44581

FromRobert Flintham <Robert.Flintham@uhb.nhs.uk>
Date2013-05-01 09:06 +0100
Message-ID<mailman.1209.1367395612.3114.python-list@python.org>
In reply to#44493
Thanks Kevin, that looks great.  It's having trouble finding TkDND though - is there a certain place in the "Python27" directory that it's most likely to look?  It's currently under Lib/site-packages, but I'm suspicious that Tk/Tkinter has its own library somewhere.

Christian - you were right.  The TkDND DLL looks to be for x64.  Is there a way around this?

All the best,
Rob



-----Original Message-----
From: Python-list [mailto:python-list-bounces+robert.flintham=uhb.nhs.uk@python.org] On Behalf Of Kevin Walzer
Sent: 01 May 2013 00:10
To: python-list@python.org
Subject: Re: Drag and drop in Windows

Official link:

http://tkinterdnd.sourceforge.net

-- 
http://mail.python.org/mailman/listinfo/python-list

DISCLAIMER:
This email and any attachments hereto contains proprietary information, some or all of which may be confidential or legally privileged. It is for the exclusive use of the intended recipient(s) only. If an addressing or transmission error has misdirected this e-mail and you are not the intended recipient(s), please notify the author by replying to this e-mail. If you are not the intended recipient you must not use, disclose, distribute, copy, print, or rely on this e-mail or any attachments, as this may be unlawful.

[toc] | [prev] | [next] | [standalone]


#44582

FromChristian Gollwitzer <auriocus@gmx.de>
Date2013-05-01 10:25 +0200
Message-ID<klqjbi$co4$1@dont-email.me>
In reply to#44581
Hi Robert,

Am 01.05.13 10:06, schrieb Robert Flintham:
> Thanks Kevin, that looks great.  It's having trouble finding TkDND
> though - is there a certain place in the "Python27" directory that
> it's most likely to look?  It's currently under Lib/site-packages,
> but I'm suspicious that Tk/Tkinter has its own library somewhere.

Does it do a "package require?" In that case, check your auto path

	tk.eval('set auto_path')
Tcl looks for the libs in the folders listed there.

> Christian - you were right.  The TkDND DLL looks to be for x64.  Is
> there a way around this?
>

Just download the right version:

http://sourceforge.net/projects/tkdnd/files/Windows%20Binaries/TkDND%202.6/

I haven't checked the content, but expect the "*ix86.tar.gz" file to be 
32 bit, whereas the "*x86_64.tar.gz" is 64 bit (despite the "win32" in 
the name).

You can extract tar.gz using winzip for example. I think it is a mistake 
to package Windows binaries using tar.gz instead of ZIP.

	Christian

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.python


csiph-web