I'm trying to make a procedure that updates the stacking order of randomly created windows based on their y value (so that things that are closer to the top of the screen display under things that are lower down). Basically I have a button that creates a window by calling a class statement. Each time a window is created, its id and y value get put in an array, which would get sorted and looped through to update the stacking order.
I figured having the id of each window that is created would be enough to change the variables of specific windows, using the id of the window.lift(), but it looks like you can't point to an object with its id like that. If I'm not mistaken I can't just use the class name because I don't want to change the whole class, just the specific window. Anybody know what I can use instead of the id to get this to work? Is it just impossible the way I have it planned? Here's my code in case it's helpful, unfinished because obviously it doesn't work:
import tkinter as tk
import random
# creates a new window
def makewndw(event):
a = testwindow()
# create main window - click to create a new window
mainwindow = tk.Tk()
mainwindow.bind('<Button-1>', makewndw)
# this sorts the windows
class stacker():
stackerwindow = tk.Toplevel()
yarray = [{'ident': 0, 'ypos': 0}]
def arupdate(self):
#sort array by ypos
self.yarray.sort(key=lambda x: x.get('ypos'))
# print(self.yarray)
# get length of array
arlen = len(self.yarray)
# loop through array between pos 1 and end
for x in range(1,arlen):
# extract dictionary from that position
tempex = self.yarray[x]
# populate temp list with values from tempex
templist = []
for i in tempex.values():
templist.append(i)
# get just the id
tempid = templist[0]
# use id to update stacking order
tempid.lift()
# ^^^ this is where i'm suck because clearly this isn't working
self.stackerwindow.after(10, self.arupdate)
class testwindow():
def __init__(self):
# create a window
self.window = tk.Toplevel()
self.y = random.randrange(100, 500)
self.window.geometry('200x200 800 {y}'.format(y=str(self.y)))
# give info to sorter
self.infdict = {'ident': id(self.window), 'ypos': self.y}
stacker.yarray.append(self.infdict)
st = stacker()
st.arupdate()
mainwindow.mainloop()
I'm a beginner so I'm sorry if the answer here is obvious, and sorry about how messy I'm sure my code is.
CodePudding user response:
To update the stacking order of the windows in your Tkinter application, you can use the lift() method on the window object itself, rather than trying to reference the object using its id.
Here is an example of how you can update the stacking order of the windows based on their y values:
import tkinter as tk
import random
# creates a new window
def makewndw(event):
a = testwindow()
# create main window - click to create a new window
mainwindow = tk.Tk()
mainwindow.bind('<Button-1>', makewndw)
# this sorts the windows
class stacker():
yarray = [{'window': 0, 'ypos': 0}]
def arupdate(self):
# sort array by ypos
self.yarray.sort(key=lambda x: x.get('ypos'))
# loop through array and update stacking order
for window_dict in self.yarray:
window_dict['window'].lift()
self.after(10, self.arupdate)
class testwindow():
def __init__(self):
# create a window
self.window = tk.Toplevel()
self.y = random.randrange(100, 500)
self.window.geometry('200x200')
self.window.geometry(' {} {}'.format(random.randrange(100, 500), self.y))
# add window to yarray
stacker.yarray.append({'window': self.window, 'ypos': self.y})
s = stacker()
s.arupdate()
mainwindow.mainloop()**
In this example, the stacker class has a method arupdate() that sorts the yarray list by the ypos value of each dictionary, and then uses the lift() method on each window object to update the stacking order. The arupdate() method is called every 10 milliseconds to continuously update the stacking order.