Newbie scoping problem

Michael P. Reilly arcege at shore.net
Wed May 12 10:16:24 EDT 1999


David Miller <dmillerON at MAPSmote.rsn.com> wrote:

: I'm trying to put together a fairly simple Tkinter application.
: In a nutshell, I want to have a root window with a scrollbox of
: "selected" files, and N "browser" windows displaying files in 
: different directories.  Double clicking on an entry in one of the
: browser windows should insert it in the root window scrollbox.

: Here's the code attached to the "New Browser" button:

:     def browsewin(self):
:         new = Toplevel()                    # replace current box
:         new.title('Testing new win')          # new resizable window
:         new.iconname("Miller_time")
:         Label(new,  text='The Ultimate Browser').pack(side=TOP)
:         list   = Listbox(new)
:         scroll = Scrollbar(new)
:         list.config(yscrollcommand=scroll.set, relief=SUNKEN, height=20, width=40)
:         list.pack(side=LEFT, expand=YES, fill=BOTH)
:         scroll.config(command=list.yview, relief=SUNKEN)
:         scroll.pack(side=RIGHT, fill=BOTH)
:         pos = 0
:         retcode = os.system("ls /etc > /tmp/ls")
:         for label in open("/tmp/ls", "r").readlines():    # Grab some text 
:             list.insert(pos, label[:-1])                  # and menu/toolbars
:             pos = pos + 1
:         list.config(selectmode=SINGLE, setgrid=1)         # select,resize modes
:         list.bind('<Double-1>', self.handleList)          # set event handler
:         self.listbox = list


: And the handleList method is pretty simple:

:     def handleList(self, event):
:         index = self.listbox.curselection()           # on listbox double-click
:         label = self.listbox.get(index)               # fetch selection text
:         print index, label                            # and call action here

: The problem:

: This seems to work fine - I can create a new browser, double-click away
: and pop text into the root scrollbox (listbox + scrollbar).  Create a 
: new browser and do the same thing.  The problem comes when going back to
: an early browser window, where the following happens:

: Exception in Tkinter callback
: Traceback (innermost last):
:   File "/usr/local/lib/python1.5/lib-tk/Tkinter.py", line 752, in __call__
:     return apply(self.func, args)
:   File "./sched.py", line 91, in handleList
:     label = self.listbox.get(index)               # fetch selection text
:   File "/usr/local/lib/python1.5/lib-tk/Tkinter.py", line 1364, in get
:     return self.tk.call(self._w, 'get', first)
: TclError: bad listbox index "": must be active, anchor, end, @x,y, or a number


: I assume this means that self.listbox.curselection() can only
: reference the most recently created listbox (browser) because I'm 
: assigning that handle when creating it.

Actually, it's a little more basic than that.  The curselection()
method is a front-end for Tcl and returns a tuple of strings (of
numbers).  You have to interpret that.

def handleList(self, event):
  index = self.listbox.curselection()
  # since the widget is in selectmode=SINGLE, there should only be one
  # item (but an empty tuple if no selection)
  if index:
    pos = int( index[0] )  # convert the first item to an integer
    label = self.listbox.get(index)
    print pos, label
  else:
    print None, None

: So how do I reference the other browser windows I've created?

: Thanks!

Also, just a tip for in your browsewin() method.  It would be more
efficient to use os.listdir() instead of the os.system() call (you also
do not remove the "/tmp/ls" file afterward).  It doesn't create another
process and even makes it (*gasp*) more portable.

  for label in os.listdir('/etc'):
    list.insert('end', label)

  -Arcege





More information about the Python-list mailing list