tkinter window geometry

Zora Honey zhoney at wildmail.com
Fri Nov 21 18:01:21 CET 2003


I realized after I posted that the window manager would be important. 
I'm on RedHat 7.1, KDE 3.0.

Neither the switch to getting the geometry through the geometry call or 
doing an update_idletasks (which I had tried before posting) works on 
their own, but together they seem to be working.  Apparently I just 
didn't hit on the right combination.

Now, if someone can tell me how I can get this to work on a Toplevel 
without having the window manager flash the "default" geometry and then 
redrawing it with my specified geometry, I would be a very happy camper.

Thanks,
Zora

P.S. To Eric Brunel--thanks for your other fixes.  The "real" code does 
check for a file and specify an exception--this was just a copy pared 
down enough for posting :)  I will take the root.quit() under 
advisement.  Can you explain why it is "better" than just exiting the 
process?


Eric Brunel wrote:
> Zora Honey wrote:
> 
>> I'm trying to get a Tkinter window to open up in the same place on my 
>> screen that I left it the last time I quit the application.  To do 
>> this, I simply write the position to a file at "exit" and at startup, 
>> I read the file.  Simple enough, but it doesn't work.  Oftentimes it's 
>> "close", but over several iterations, the window will wander all over 
>> the screen. In the output below, you can see that the x offset is 
>> "off" by +4 each iteration.  Until I move the window.  Then x and y 
>> are off for one iteration.  Then back to just x.
>>
>> Anybody know what the heck is going on here?
> 
> 
> Window geometry is handled by the window manager you're using, so 
> knowing your platform and your window manager would help.
> 
> Anyway:
> 
> [snip script output]
> 
>> -------Code--------
>> from Tkinter import *
>>
>> if __name__=="__main__":
>>      def die():
>>         root.update_idletasks()
>>         newGeometry='+%d+%d' % (root.winfo_x(), root.winfo_y())
> 
> 
> That's one problem: you cannot be assured that winfo_rootx() and 
> winfo_rooty() will actually return the same coordinates as geometry() 
> does. AFAICT, the only valid input for geometry() is a former output 
> from geometry(). So I'd do something like:
> 
> newGeometry = root.geometry()
> i = newGeometry.find('+')
> if i != -1:
>   newGeometry = newGeometry[i:]
>   print "out=", newGeometry
>   if newGeometry != geometryConfig:
>     ...
> root.quit()   # Better than a sys.exit(0)
> 
> 
>>         print "out=", newGeometry
>>         if (newGeometry!=geometryConfig):
>>             config=open("alarm.config", 'w')
>>             config.write(newGeometry+'\n')
>>         sys.exit(0)
>>
>>      root=Tk()
>>      try:
>>          config=open("alarm.config")
>>          geometryConfig=config.readline()[:-1]
>>          config.close()
>>          print "in=", geometryConfig
>>          print "before=,", root.geometry(newGeometry=None)
> 
> 
> Here, you set the geometry before the root window is actually built. It 
> may be a problem. So I'd pack the button in the window and do an 
> update_idletasks before reading and setting the geometry. I don't know 
> if it will change anything to the behavior you get, but it may make your 
> script more portable.
> 
>>          root.geometry(newGeometry=geometryConfig)
>>          root.update()
>>          print "after=", root.geometry(newGeometry=None)
>>      except :
>>          pass
> 
> 
> Another (unrelated) problem: if the file alarm.config does not exist, 
> geometryConfig is never set and the die function will crash... And I 
> won't repeat here how much a bad habit it is to use "except:" without an 
> exception type... ;-)
> 
>>      exitb=Button(root, text="Exit", command=die)
>>      exitb.pack(side=LEFT)
>>
>>      root.mainloop()
>>
> 
> Your script with all the modifications I've described works as expected 
> on Linux Mandrake 8 with Python 2.1 and tcl/tk 8.3.4, with the KDE 
> window manager.
> 
> HTH






More information about the Python-list mailing list