Dear all,

in my application I have developed a small widget class "InPlaceEdit" to allow the user to edit in place the content of an item from a listbox. The class is creating a temporary popup Entry() (or overridden with any other widget) and placing it exactly on the coordinates of the listbox item to edit.

Now my problem is the following. I am binding the <FocusOut> so when the user clicks outside the widget, to destroy the widget and replace the value in the listbox. But, if the user clicks on a button, then the program first executes the command of the button and then it sends the <FocusOut> event to the InPlaceEdit, with an end result that the content is updated after the command is executed. The same happens also with Menu entries.

What should I bind to get a notification that I will lose the focus (or something similar) before executing the command of the button?

Vasilis


#===============================================================================
# Class to edit in place the contents of a listbox
#===============================================================================
class InPlaceEdit:
   def __init__(self, listbox, item=ACTIVE, value=None):
       # Return value
       self.value = None    # Result
       self.item  = item

       # Find active
       try: self.active = listbox.index(self.item)
       except: return

       self.listbox = listbox

       # Create and set value
       self.frame = Frame(listbox, relief=None)
       self.createWidget()
       self.set(value)
       self.defaultBinds()

       # Bindings
       self.frame.bind("<FocusOut>", self.focusOut)
       self.frame.bind("<Unmap>", self.cancel)
       self.listbox.bind("<Configure>", self.resize)

       # Show and wait to be destroyed
       self.resize()
       self.frame.wait_window()

   # ----------------------------------------------------------------------
   # Override method if another widget is requested
   # ----------------------------------------------------------------------
   def createWidget(self):
       self.edit = Entry(self.frame, background="White")
       self.edit.pack(expand=YES, fill=BOTH)
       self.edit.focus_set()

   # ----------------------------------------------------------------------
   # Set default bindings
   # ----------------------------------------------------------------------
   def defaultBinds(self):
       try:
           self.edit.bind("<Return>", self.ok)
           self.edit.bind("<Escape>", self.cancel)
       except AttributeError:
           pass

   # ----------------------------------------------------------------------
   def resize(self, event=None):
       x, y, w, h = self.listbox.bbox(self.item)
       w = self.listbox.winfo_width()
       h += 2
       try:
           self.frame.place(in_=self.listbox,
                   x=x-1, y=y-1,
                   width=w, height=h,
                   bordermode=OUTSIDE)
           self.frame.update_idletasks()
       except TclError:
           pass

   # ----------------------------------------------------------------------
   # Override method to set the value
   # ----------------------------------------------------------------------
   def set(self, value):
       if value is None:
           value = self.listbox.get(self.item)
       self.edit.delete(0, END)
       self.edit.insert(0, value)
       self.edit.selection_range(0, END)

   # ----------------------------------------------------------------------
   # Override method to get the value
   # ----------------------------------------------------------------------
   def get(self):
       return self.edit.get()

   # ----------------------------------------------------------------------
   def ok(self, event=None):
       self.value = self.get()
       self.frame.unbind('<FocusOut>')
       self.frame.place_forget()
       self.frame.destroy()
       self.listbox.focus_set()
       act = self.listbox.index(ACTIVE)
       sel = self.listbox.selection_includes(self.active)
       self.listbox.delete(self.active)
       self.listbox.insert(self.active, self.value)
       if sel:
           self.listbox.selection_set(self.active)
       self.listbox.activate(act)
       return "break"

   # ----------------------------------------------------------------------
   def focusOut(self, event=None):
       self.ok()

   # ----------------------------------------------------------------------
   def cancel(self, event=None):
       self.frame.place_forget()
       self.frame.destroy()
       self.listbox.focus_set()
       return "break"

begin:vcard
fn:Vasilis Vlachoudis
n:Vlachoudis;Vasilis
org:CERN;AB
adr:CERN;;Dep.AB;Geneva-23;;CH-1211;Switzerland
email;internet:[EMAIL PROTECTED]
title:Dr
tel;work:+41-22-767.9851
tel;fax:+41-22-766.9644
tel;cell:+41-76-487.4378
x-mozilla-html:FALSE
url:http://home.cern.ch/bnv
version:2.1
end:vcard

_______________________________________________
Tkinter-discuss mailing list
Tkinter-discuss@python.org
http://mail.python.org/mailman/listinfo/tkinter-discuss

Reply via email to