Tkinter: Relative positioning of Toplevels

Eric Brunel eric.brunel at pragmadev.com
Tue Jul 23 04:31:57 EDT 2002


Julie Torborg wrote:

> Hello.
> 
> I was wondering if anyone can tell me how to position a toplevel
> relative to another widget.
> 
> Basically, I want to end up with something that behaves like a
> pull-down menu, except that you can't select anything--it just
> displays information. I'm not clever enough to hack the OptionMenu
> class, so I've been trying to use a button/toplevel combination.  I
> want the toplevel to appear "anchored" to the button.  The problem is,
> I can't get the toplevel to show up anywhere near the button. I use
> 
> self.x=nb.winfo_geometry()
> 
> to get the position of the button relative to it's parent, but when I
> do:
> 
> self.tl.geometry(self.x)
> 
> it draws the toplevel with these coordinates relative to the screen.

AFAIK, there is no way to position a widget relatively to another one, nor 
any method returning the geometry of a widget relative to the screen. But 
the last one is quite simple to get: use the winfo_rootx, winfo_rooty and 
winfo_height methods. If you write your code this way (untested):

> class eachModule:
>     def __init__(self, pf):
>         self.pf=pf
          ## Remember the button
          self.nb=Button(self.pf, text="Popup")
          self.nb.bind("<ButtonPress-1>", self.pr)
          self.nb.bind("<ButtonRelease-1>", self.rel)
          self.nb.pack()

>     
>     def pr(self, event):
>         self.tl=Toplevel(self.pf)
>         self.tl.overrideredirect(1)

          ## Geometry is button's bottom left corner
          g = "+%s+%s" % (
            self.nb.winfo_rootx(),
            self.nb.winfo_rooty() + self.nb.winfo_height()
          )
          self.tl.geometry(g)
>         label=Label(self.tl, text="info up")
>         label.pack()
> 
>     def rel(self, event):
>         self.tl.destroy()
> 
> 
> if __name__=="__main__":
> 
>     def die():
>         root.quit()
>         root.destroy()
>         
>     root=Tk()
> 
>     em=eachModule(root)
>     
>     eb=Button(root, text="Exit", command=die)
>     eb.pack()
>     root.mainloop()

it should work as you want...

HTH
-- 
- Eric Brunel <eric.brunel at pragmadev.com> -
PragmaDev : Real Time Software Development Tools - http://www.pragmadev.com



More information about the Python-list mailing list