Search code examples
tkinterpositiongeometrypython-3.3

Positioning a window as it changes in size


What I am trying to do is keep my window positioned in the upper right corner of the screen. As you navigate through different options, the window changes size based on what is displayed. So I need something that checks the windows current size, then positions it based on its size.

My code:

from tkinter import *

class Main:
    def __init__(self, master):
        self.master = master
        self.win_1()

    def win_1(self):
        for child in self.master.winfo_children():
            child.destroy()
        Text(self.master, width = 10, height = 3).grid(columnspan = 2)
        Button(self.master, text = 'Win 2', width = 7, command = self.win_2).grid(row = 2, column = 0)
        Button(self.master, text = 'Exit', width = 7, command = self.master.destroy).grid(row = 2, column = 1)    
        self.position_win()

    def win_2(self):
        for child in self.master.winfo_children():
            child.destroy()
        Text(self.master, width = 20, height = 10).grid()
        Button(self.master, text = 'Win 1', command = self.win_1).grid()
        self.position_win()

    def position_win(self):
        self.h = self.master.winfo_height()
        self.w = self.master.winfo_width()
        self.master.geometry('-%d+%d' % (self.w, self.h))


root = Tk()
Main(root)

root.mainloop()

This was the best I could come up with to accomplish my goal. When I run this, the window starts out perfectly placed in the upper right corner. When you click the button, the upper right corner of window 2 gets set at the lower left corner of window 1. Then when you click back to window 1, it sets the upper right corner to the same position as it was in window 2. From this point, cycling between the windows works off the upper right corner of the window, but the windows are not in the upper right corner of the screen. I'm sure that is clear as mud, but if you run the code you will see what I'm talking about.

Why is it doing this and how do I fix it?

Thanks!


Solution

  • Your program is doing just what you tell it to do. Quoting from http://infohost.nmt.edu/tcc/help/pubs/tkinter/web/geometry.html "If the next part has the form +x, it specifies that the left side of the window should be x pixels from the left side of the desktop. If it has the form -x, the right side of the window is x pixels from the right side of the desktop. "

    So you are telling tk to put the window the width of the previous window away from the right edge. Similarly for the vertical position. The only 'mystery' is why it is in the corner the first time. The reason is that self.master.geometry() is initially 1x1+0+0 and not affected by the grid operations. If you want the window in a constant place, put it where you want in the __init__ method with self.master.geometry('-0+0') and delete the position method and calls.

    Note: an alternate approach to creating and destroying widgets is to create two frames, and switch by grid_forgeting one and griding the other. Or grid both and lift the one you want on top. The latter makes the window big enough to hold both.