From klappnase at web.de Tue Jul 5 13:05:29 2005 From: klappnase at web.de (Michael Lange) Date: Tue, 5 Jul 2005 13:05:29 +0200 Subject: [Tkinter-discuss] python wrapper for tkDnD Message-ID: <20050705130529.6eb764f7.klappnase@web.de> Hello list, looking for a way to achieve inter-application drag and drop capabilities for Tkinter I came to look at the tkDnD extension for tcl/tk (http://sourceforge.net/projects/tkdnd) which adds native drag and drop support on windows and unix. I couldn't find some approach to write a python interface for it anywhere though, so I decided to try and write my own. I currently got it at least partially working; before I do more detail work and testing I would like to ask the experts here, what you think about the general approach I used. (See the code below, a small demo included) I could also use a helping hand on some of the tk related things, the way I create the command strings for tk doesn't look very good to me , but I cannot figure out how to do it better. Any feedback is highly appreciated. Thanks in advance Michael ############### file DnD.py ############################################################### '''Python wrapper for the tkDnD tk extension.''' class DnD: def __init__(self, tkroot): self._tkroot = tkroot tkroot.tk.eval('package require tkdnd') # make self an attribute of the parent window for easy access in child classes tkroot.dnd = self def bindsource(self, widget, type=None, command=None, arguments=None, priority=None): '''Register widget as drag source; for details on type, command and arguments, see bindtarget(). priority can be a value between 1 and 100, where 100 is the highest available priority (default: 50). If command is omitted, return the current binding for type; if both type and command are omitted, return a list of registered types for widget.''' command = self._generate_callback(command, arguments) tkcmd = self._generate_tkcommand('bindsource', widget, type, command, priority) res = self._tkroot.tk.eval(tkcmd) if type == None: res = res.split() return res def bindtarget(self, widget, type=None, sequence=None, command=None, arguments=None, priority=None): '''Register widget as drop target; type may be one of text/plain, text/uri-list, text/plain;charset=UTF-8 (see the man page tkDND for details on other (platform specific) types); sequence may be one of '', '', '', '' or '' ; command is the callback associated with the specified event, argument is an optional tuple of arguments that will be passed to the callback; possible arguments include: %A %a %b %C %c %D %d %L %m %T %t %W %X %x %Y %y (see the tkDND man page for details); priority may be a value in the range 1 to 100 ; if there are bindings for different types, the one with the priority value will be proceeded first (default: 50). If command is omitted, return the current binding for type, where sequence defaults to ''. If both type and command are omitted, return a list of registered types for widget.''' command = self._generate_callback(command, arguments) tkcmd = self._generate_tkcommand('bindtarget', widget, type, sequence, command, priority) res = self._tkroot.tk.eval(tkcmd) if type == None: res = res.split() return res def clearsource(self, widget): '''Unregister widget as drag source.''' self._tkroot.tk.call('dnd', 'clearsource', widget) def cleartarget(self, widget): '''Unregister widget as drop target.''' self._tkroot.tk.call('dnd', 'cleartarget', widget) def drag(self, widget, actions=None, descriptions=None, cursorwindow=None, command=None, arguments=None): '''Initiate a drag operation with source widget.''' command = self._generate_callback(command, arguments) if actions: if actions[1:]: actions = '-actions {%s}' % ' '.join(actions) else: actions = '-actions %s' % actions[0] if descriptions: descriptions = ['{%s}'%i for i in descriptions] descriptions = '{%s}' % ' '.join(descriptions) if cursorwindow: cursorwindow = '-cursorwindow %s' % cursorwindow tkcmd = self._generate_tkcommand('drag', widget, actions, descriptions, cursorwindow, command) self._tkroot.tk.eval(tkcmd) def _generate_callback(self, command, arguments): '''Register command as tk callback with an optional list of arguments.''' cmd = None if command: cmd = self._tkroot._register(command) if arguments: cmd = '{%s %s}' % (cmd, ' '.join(arguments)) return cmd def _generate_tkcommand(self, base, widget, *opts): '''Create the command string that will be passed to tk.''' tkcmd = 'dnd %s %s' % (base, widget) for i in opts: if i is not None: tkcmd += ' %s' % i return tkcmd #############--demo code--######################################## def test(): import Tkinter root = Tkinter.Tk() dnd = DnD(root) Tkinter.Label(root, text='Drop files from your file manager into the listbox').pack(side='top') l = Tkinter.Listbox(root) l.pack(side='top', fill='both', expand=1) root.update()# may be necessary on unix # now make the listbox a drop target: def drag(action, actions, type, win, X, Y, x, y, data): return action def drag_enter(action, actions, type, win, X, Y, x, y, data): l.focus_force() return action def drop(action, actions, type, win, X, Y, x, y, data): files = data.split() for f in files: l.insert('end', f) dnd.bindtarget(l, 'text/uri-list', '', drag, ('%A', '%a', '%T', '%W', '%X', '%Y', '%x', '%y', '%D')) dnd.bindtarget(l, 'text/uri-list', '', drag_enter, ('%A', '%a', '%T', '%W', '%X', '%Y', '%x', '%y', '%D')) dnd.bindtarget(l, 'text/uri-list', '', drop, ('%A', '%a', '%T', '%W', '%X', '%Y', '%x', '%y','%D')) root.mainloop() if __name__ == '__main__': test() ################ end of DnD.py ####################################################### From klappnase at web.de Thu Jul 7 12:43:04 2005 From: klappnase at web.de (Michael Lange) Date: Thu, 7 Jul 2005 12:43:04 +0200 Subject: [Tkinter-discuss] Again: python wrapper for tkDnD Message-ID: <20050707124304.75385e88.klappnase@web.de> Hello again, after some more hours of work on the tkDnD python wrapper I came to use a new concept, which makes the Tk dnd and shape commands directly accessable from any Tkinter widget. As far as I have tested (not very far, though) it seems to work now. However, it is the first time for me to try writing a python wrapper for a Tk extension, so I am still not sure about the way to go. Anyone who is interested can find it at: http://www.8ung.at/klappnase/TkinterDnD/TkinterDnD.html Any feedback is much appreciated. Best regards Michael From rowen at cesmail.net Thu Jul 7 22:53:04 2005 From: rowen at cesmail.net (Russell E. Owen) Date: Thu, 07 Jul 2005 13:53:04 -0700 Subject: [Tkinter-discuss] Avoiding memory leaks using tk.call Message-ID: I'm writing code that retrieves URLs to files on disk using tcl's http module. (Why bother? See P.S.) So far, so good, but I'm a bit worried I may be leaking memory. Thus I open the output file and start the transfer with: self._tclFile = self._tkApp.call('open', self.toPath, mode) mode,)) self._tclHTTPConn = self._tkApp.call( '::http::geturl', self.url, '-channel', self._tclFile, '-command', self._tclHTTPDoneCallback, '-progress', self._tclHTTPProgressCallback, '-binary', self.isBinary, '-timeout', self.timeLimMS ) And clean up afterwards using: self._tclHTTPConn != None: self._tkApp.call("::http::cleanup", self._tclHTTPConn) self._tclHTTPConn = None self._tclFile: self._tkApp.call("close", self._tclFile) self._tclFile = None and I delete the callbacks from tcl using self._tkApp.deletecommand. It works, but I'm wondering if I'm leaking the reference to the file or http connection that was created inside tcl. If so, any hints on how to clean those up would be much appreciated. -- Russell P.S. why bother: - I don't want my users to have to install Twisted framework. Though I get closer to that every time something like this comes up. - I've tried using the built in python libraries for stuff like this, but it's a hassle due to no integration with the tk event loop. The resulting code does work, but doing without blocking is painful as is keeping track of state. Plus I've had reports of occasional failures that I can't reproduce on my computer. P.P.S. The resulting code will be released in an update to my free RO package . The package already includes tk sockets and lots of other goodies. From shallu_gupta2000 at yahoo.com Fri Jul 15 08:17:53 2005 From: shallu_gupta2000 at yahoo.com (Shallu Gupta) Date: Thu, 14 Jul 2005 23:17:53 -0700 (PDT) Subject: [Tkinter-discuss] Fwd: Message-ID: <20050715061753.59048.qmail@web50702.mail.yahoo.com> Note: forwarded message attached. Lead me from the unreal to the real Lead me from darkness to light Lead me from death to immortality. -Invocation from the Upanishads __________________________________________________ Do You Yahoo!? Tired of spam? Yahoo! Mail has the best spam protection around http://mail.yahoo.com -------------- next part -------------- An embedded message was scrubbed... From: Shallu Gupta Subject: Date: Thu, 14 Jul 2005 21:39:52 -0700 (PDT) Size: 2096 Url: http://mail.python.org/pipermail/tkinter-discuss/attachments/20050714/d0f40570/attachment.eml From shallu_gupta2000 at yahoo.com Fri Jul 15 08:28:06 2005 From: shallu_gupta2000 at yahoo.com (Shallu Gupta) Date: Thu, 14 Jul 2005 23:28:06 -0700 (PDT) Subject: [Tkinter-discuss] Message-ID: <20050715062806.60263.qmail@web50702.mail.yahoo.com> Respected Sir I need ur favour... i just started using Python....Actually i wanna work with Graphics in python So whenver i write " from graphics Import *" i get following message "Traceback (Most Recent Call last); File "', line1,in? File "/staff/shalu/python-2.4.1/lib/graphics.py".line ? import TKinter File "/staff/shalu/python-2.4.1/lib/lib_tk/TKinter.py" import_TKinter # if this fails your Python may not be configured for TK import Error: no module named _TKinter Plz help me out.... tell me how to configure Python wiht Tk. Regards Shalu Lead me from the unreal to the real Lead me from darkness to light Lead me from death to immortality. -Invocation from the Upanishads __________________________________________________ Do You Yahoo!? Tired of spam? Yahoo! Mail has the best spam protection around http://mail.yahoo.com From klappnase at web.de Wed Jul 20 10:29:02 2005 From: klappnase at web.de (Michael Lange) Date: Wed, 20 Jul 2005 08:29:02 -0000 Subject: [Tkinter-discuss] pybwidget Message-ID: <20050214194230.4097aa10.klappnase@web.de> I've been playing around with pybwidget a little and found two bugs that stop the ListBox and Tree widgets from working. First, the "plus" and "minus" bitmaps are missing from the images directory, so you cannot set the drawcross option in bwidget.Tree.insert() to "auto" or "allways". Second there's a typo in ListBox.insert(): __init__.py line 455: def insert(self, index, item="#auto", **kw): return self.tk.call(self._w, "insert", parent, item,# this must be "index" *self._options(kw)) ^^^^^^ From jay.taneja at gmail.com Thu Jul 21 06:10:17 2005 From: jay.taneja at gmail.com (Jay Taneja) Date: Wed, 20 Jul 2005 21:10:17 -0700 Subject: [Tkinter-discuss] Switching between Entry widgets Message-ID: hi everyone - i'm relatively new to python/tkinter, so it may be something pretty silly i've overlooked. the tkinter application i have written has two entry widgets and two buttons. what i would like is for the focus to be on the first entry widget, such that i launch the program and can immediately input text into the entry box. for some reason, i am unable to get the focus() command working for me. additionally, the input device i am using to put text in the entry boxes ends in a carriage return. as soon as this carriage return is received in the first entry box, i would like the focus to go to the second entry box. when the second entry box gets a carriage return, i would like to issue the callback of the first button widget. this all seems to make sense in my head, binding the keypress to switch the focus, but i can't seem to get everything working correctly. the program doesn't respond to my bindings and i can't get the focus switching to work at all. any help would be greatly appreciated. thank you. -jay From klappnase at web.de Thu Jul 21 10:36:00 2005 From: klappnase at web.de (Michael Lange) Date: Thu, 21 Jul 2005 10:36:00 +0200 Subject: [Tkinter-discuss] Switching between Entry widgets In-Reply-To: References: Message-ID: <20050721103600.4bde573c.klappnase@web.de> Hi Jay, can you post some of the code that doesn't work for you, it's easier to figure out what's going wrong if we see what you have so far. On Wed, 20 Jul 2005 21:10:17 -0700 Jay Taneja wrote: > the tkinter application i have written has two entry widgets and two > buttons. what i would like is for the focus to be on the first entry > widget, such that i launch the program and can immediately input text > into the entry box. for some reason, i am unable to get the focus() > command working for me. > > additionally, the input device i am using to put text in the entry > boxes ends in a carriage return. as soon as this carriage return is > received in the first entry box, i would like the focus to go to the > second entry box. when the second entry box gets a carriage return, i > would like to issue the callback of the first button widget. > > this all seems to make sense in my head, binding the keypress > to switch the focus, but i can't seem to get everything working > correctly. the program doesn't respond to my bindings and i can't get > the focus switching to work at all. > Just a shot in the dark: maybe you didn't handle the event bind() passes to the callback correctly, like this: entry1.bind('', button1.focus)# wrong! bind() passes the event to focus() and focus() doesn't accept this as argument. There are basically two ways to work around this: 1 - use a lambda that catches the event: entry1.bind('', lambda event : button1.focus()) 2 - use an extra method as callback that accepts the event as argument: def switch_focus(event): button1.focus() entry1.bind('', switch_focus) The advantage of the second option is especially that you can use the information the event provides, e.g.: def switch_focus(event): if event.widget == entry1: button1.focus() elif event.widget == entry2: button2.focus() button2.invoke() If the problem lies somewhere else, please post some of your code. Best regards Michael From mfranklin1 at gatwick.westerngeco.slb.com Thu Jul 21 11:53:40 2005 From: mfranklin1 at gatwick.westerngeco.slb.com (Martin Franklin) Date: Thu, 21 Jul 2005 10:53:40 +0100 Subject: [Tkinter-discuss] Switching between Entry widgets In-Reply-To: References: Message-ID: Jay Taneja wrote: > hi everyone - i'm relatively new to python/tkinter, so it may be > something pretty silly i've overlooked. > > the tkinter application i have written has two entry widgets and two > buttons. what i would like is for the focus to be on the first entry > widget, such that i launch the program and can immediately input text > into the entry box. for some reason, i am unable to get the focus() > command working for me. > > additionally, the input device i am using to put text in the entry > boxes ends in a carriage return. as soon as this carriage return is > received in the first entry box, i would like the focus to go to the > second entry box. when the second entry box gets a carriage return, i > would like to issue the callback of the first button widget. > > this all seems to make sense in my head, binding the keypress > to switch the focus, but i can't seem to get everything working > correctly. the program doesn't respond to my bindings and i can't get > the focus switching to work at all. > > any help would be greatly appreciated. thank you. > > -jay Jay, The method you are looking for is focus_set, also this will be used to change the focus when you press return somthing like this:- e1 = Entry(root) e1.pack() e2 = Entry(root) e2.pack() def return_bind(event): """called when event in e1 will give the focus to e2 """ e2.focus_set() e1.bind("", return_bind) # give the focus to e1 at the start e1.focus_set() Martin From DFDahlke at shieldsbag.com Thu Jul 21 23:15:10 2005 From: DFDahlke at shieldsbag.com (Dahlke, Doug) Date: Thu, 21 Jul 2005 14:15:10 -0700 Subject: [Tkinter-discuss] errors in versions? Message-ID: <5F063358AA124D43AE65BE83F89A0162791DCD@sbpnt6.shields.com> I guess I'm a semi-newbie to python. I played with it a number of years ago and thought this was way better than perl in some respects. Going over the old 'Learning Python' book again I tried a couple of the gotchas. I realize I'm running some fairly old versions of python, but shouldn't be too out of date. I have the windows version PythonWin 2.3.2 (#49, Nov 13 2003, 10:34:54) [MSC v.1200 32 bit (Intel)] on win32. On our SCO system, yes I know.. why?, I'm running Python 2.4.1 (#10, Jun 27 2005, 16:01:01) [C] on unixware7. One would think these are fairly close together as far as updates. I am running the PythonWin app on my windows so maybe that's why. Anyway, running the 'Gotchas' on page 121 as below, the windows version works as you would hope it would, you get the answer 81 as you would expect if you didn't know it was a gotcha. On the unix server, you get 16 which is what the book says. Here is the code: >>> def outer(x,y): ... def inner(a=x, b=y): ... return a**b ... return inner ... >>> x = outer(2,4) >>> x() 16 Just wonder if anyone else found that to be a problem with levels Doug Dahlke I.T. Dept Shields Bag and Printing From DFDahlke at shieldsbag.com Thu Jul 21 23:31:16 2005 From: DFDahlke at shieldsbag.com (Dahlke, Doug) Date: Thu, 21 Jul 2005 14:31:16 -0700 Subject: [Tkinter-discuss] opps, never mind Message-ID: <5F063358AA124D43AE65BE83F89A0162791DCF@sbpnt6.shields.com> Ah ha, never mind. Silly typo was all. Forget post. It's the same.