[Patches] Tkinter OptionMenu callback

bwarsaw@CNRI.Reston.VA.US bwarsaw@CNRI.Reston.VA.US
Thu, 24 Feb 2000 15:48:07 -0500 (EST)


>>>>> "GvR" == Guido van Rossum <guido@python.org> writes:

    GvR> Nice, it seems that Pmw's OptionMenu has the same
    GvR> functionality.

Exactly my motivation!  I didn't want to pull in all of Pmw just for
this useful feature (well, I didn't want Andrew to have to do that :).

    GvR> (1) Shouldn't the _setit() class set the variable before
    GvR> calling the callback?

Yes.

    GvR> (2) You should check that the only kw arg accepted is
    GvR> 'command'.  The current code silently ignores other kw args,
    GvR> which is very un-Tk-ish.

Done, but in a slightly kludgy way, since Tk never sees this option.
See what you think about this hack.
    
    GvR> (I would also undo the rename of the 'kw' dict

Agreed.

One other thing.  I might argue that there should be a `configure'
method that allows you to change the callback, but I on the other
hand, it's probably not important enough to add.a

    GvR> I noticed that you didn't include the legal boilerplate <2.0
    GvR> wink>.

Well /I/ shouldn't need to do that, and Randall didn't include the
boilerplate on his posted patch (from which mine was derived).  Hmm,
maybe we should ask Randall to add the boilerplate to his original
patch, and submit that to patches@python.org?  On the other hand,
maybe the patch below looks different enough from Randall's that his
disclaimer isn't necessary (although we'll still give due credit of
course)?

-Barry

-------------------- snip snip --------------------
Index: Tkinter.py
===================================================================
RCS file: /projects/cvsroot/python/dist/src/Lib/lib-tk/Tkinter.py,v
retrieving revision 1.134
diff -c -r1.134 Tkinter.py
*** Tkinter.py	1999/10/20 12:29:56	1.134
--- Tkinter.py	2000/02/24 20:39:27
***************
*** 1790,1803 ****
  		self.tk.call((self._w, 'yview', '-pickplace') + what)
  
  class _setit:
! 	def __init__(self, var, value):
  		self.__value = value
  		self.__var = var
  	def __call__(self, *args):
  		self.__var.set(self.__value)
  
  class OptionMenu(Menubutton):
! 	def __init__(self, master, variable, value, *values):
  		kw = {"borderwidth": 2, "textvariable": variable,
  		      "indicatoron": 1, "relief": RAISED, "anchor": "c",
  		      "highlightthickness": 2}
--- 1790,1806 ----
  		self.tk.call((self._w, 'yview', '-pickplace') + what)
  
  class _setit:
! 	def __init__(self, var, value, callback=None):
  		self.__value = value
  		self.__var = var
+ 		self.__callback = callback
  	def __call__(self, *args):
  		self.__var.set(self.__value)
+ 		if self.__callback:
+ 			apply(self.__callback, (self.__value,)+args)
  
  class OptionMenu(Menubutton):
! 	def __init__(self, master, variable, value, *values, **kwargs):
  		kw = {"borderwidth": 2, "textvariable": variable,
  		      "indicatoron": 1, "relief": RAISED, "anchor": "c",
  		      "highlightthickness": 2}
***************
*** 1805,1813 ****
  		self.widgetName = 'tk_optionMenu'
  		menu = self.__menu = Menu(self, name="menu", tearoff=0)
  		self.menuname = menu._w
! 		menu.add_command(label=value, command=_setit(variable, value))
  		for v in values:
! 			menu.add_command(label=v, command=_setit(variable, v))
  		self["menu"] = menu
  
  	def __getitem__(self, name):
--- 1808,1824 ----
  		self.widgetName = 'tk_optionMenu'
  		menu = self.__menu = Menu(self, name="menu", tearoff=0)
  		self.menuname = menu._w
! 		# 'command' is the only supported keyword
! 		callback = kwargs.get('command')
! 		if callback:
! 			del kwargs['command']
! 		if kwargs:
! 			raise TclError, 'unknown option -'+kwargs.keys()[0]
! 		menu.add_command(label=value,
! 				 command=_setit(variable, value, callback))
  		for v in values:
! 			menu.add_command(label=v,
! 					 command=_setit(variable, v, callback))
  		self["menu"] = menu
  
  	def __getitem__(self, name):