A Dangling Tk Entry

Rhodri James rhodri at wildebst.demon.co.uk
Wed Mar 11 01:37:59 CET 2009


On Tue, 10 Mar 2009 12:41:07 -0000, W. eWatson <notvalid2 at sbcglobal.net>  
wrote:

[snippety snip]

> Rhodri James wrote:
>  > You're misunderstanding.  The line that you arrowed above has  
> absolutely
>  > nothing whatsoever to do with the method "body()", so keeping on  
> showing
>  > us ever fuller version of that isn't going to prove anything.  Now if
>  > you were to show us a line like "something =  
> dialog.body(something_else)"
>  > then you might be onto something, but personally I suspect you're  
> going
>  > to find that rather hard.
>  >
> I'd be happy to comply. Perhaps I'm mistaken as what I was responding to  
> in the entanglement of responses, but I think I was making a point  
> (again) that the technique by the author works. This should clear  
> matters up completely. Here's the full 80+ lines of the example code.  
> Note wrapped lines.
> ================================
> from Tkinter import *
> import tkSimpleDialog
> import tkMessageBox
>
> class IntVar_GUI:
>
>      def __init__(self, master):
>
>          master.title('Control Variable Fun')
>
>          self.frame = Frame(master,takefocus=1,
>                             highlightthickness=2, highlightcolor='blue')
>          self.frame.configure(height=200,width=200)
>          self.frame.pack()
>          #self.frame.bind("<KeyPress>", self.HandleKey)
>
>          self.anumber = 123      # Want name and value to be configurable
>
>          self.master = master
>          menu = Menu(master)
>          master.config(menu=menu)
>
>          self.mainMenu = Menu(menu)
>          menu.add_cascade(label="My Menu",menu=self.mainMenu)
>          self.mainMenu.add_command(label="Enter Data",  
> command=self.Set_Enter_Data)
>          self.mainMenu.add_command(label="Exit",underline=1,command=self.Quit)
>          self.Focus()
>
>
>      def Set_Enter_Data(self):
>          sdict = {}
>          sdict[ "ok" ] = False
>          sdict[ "anumber" ] = self.anumber
>          dialog = Enter_Data_Dialog( self.master, sdict )
>          self.Focus()
>          print "Howdy, set data. Number is:", dialog.anumberVar.get()
>          print "dict:", dialog.sdict
>          if not dialog.sdict["ok"]:
>              return
>          try:
>              self.anumber = int(eval(dialog.anumberVar.get()))
>              print "OK"
>          except:
>              print "Not OK"
>              pass
>          print "self.anumber:", self.anumber
>
>      def Quit(self):
>          self.running = False
>          #self.master.quit()
>          self.master.destroy()
>
>      def Focus( self ):
>          self.frame.focus_set()
>
> class Enter_Data_Dialog(tkSimpleDialog.Dialog):
>
>      def __init__(self, parent, sdict):
>          self.sdict = sdict
>          tkSimpleDialog.Dialog.__init__(self, parent)
>
>      def body(self,master):
>          self.title("Set a Number Entry Dialog")
>
>          Label( master, text="Number ").grid(row=0, sticky=W)
>          self.anumberVar = StringVar()
>          entry = Entry(master, width=10,  
> textvariable=self.anumberVar).grid(row=0, column=1)
>          entry.insert(0,11)
>          self.anumberVar.set( "%d" % self.sdict["anumber"] )
>
>          return entry
>
>      def apply(self):
>          self.sdict["ok"] = True
>
> def Process():
>      root = Tk()
>      app = IntVar_GUI(root)
>      root.mainloop()
>
> if __name__ == "__main__":
>      Process()
> ====================================
> Because I'm operating out for a command prompt, I don't seem to be able  
> to copy all the error msgs, but here is the last one shown involving  
> line 68,
> AttributeError: "None Type' object has no attribute 'insert'
>
> Line 68 is entry.insert(0,11)

I'm operating from the command line too.  The traceback is:

"""
Exception in Tkinter callback
Traceback (most recent call last):
   File "/usr/lib/python2.5/lib-tk/Tkinter.py", line 1406, in __call__
     return self.func(*args)
   File "temp.py", line 34, in Set_Enter_Data
     dialog = Enter_Data_Dialog( self.master, sdict )
   File "temp.py", line 60, in __init__
     tkSimpleDialog.Dialog.__init__(self, parent)
   File "/usr/lib/python2.5/lib-tk/tkSimpleDialog.py", line 64, in __init__
     self.initial_focus = self.body(body)
   File "temp.py", line 68, in body
     entry.insert(0,11)
AttributeError: 'NoneType' object has no attribute 'insert'
"""

In other words "entry" is None.  This is the "entry" that's a local  
variable in the Enter_Data_Dialog class "body" method (called  
automatically by tkSimpleDialog.Dialog.__init__, it turns out, so my  
apologies for implying that it wasn't called at all), the one that's  
created by the line

entry = Entry(master,...).grid(row=0,...)

Given that this is what "grid" is expected to return, this shouldn't be  
the shock that apparently it is.  This "entry" is also the return value  
 from "body", which won't be helpful.  The Dialog documentation says this:

"""body(self, master)
create dialog body.

return widget that should have initial focus.
This method should be overridden, and is called
by the __init__ method."""

This suggests that the code originally looked like this:

entry = Entry(master,...)
entry.grid(row=0,...)

and someone decided to "optimise" it.  Put it back the way it used to be,  
and your problem will magically vanish.

-- 
Rhodri James *-* Wildebeeste Herder to the Masses



More information about the Python-list mailing list