Home > Back-end >  Is there a way to change draw order for existing shapes in Tkinter canvas ( over a video stream)
Is there a way to change draw order for existing shapes in Tkinter canvas ( over a video stream)

Time:06-21

I am getting a video stream using socket, and displaying it on a canvas. I am attempting to have a box that can be moved using sliders to position over a certain object in frame. the issue is I'm not redrawing the shape i guess, so it's getting drawn under the stream. is there any way around this? should i double layer a canvas in the grid so it's drawn on top?

                    self.tempImage = self.tempImage.resize((int(self.videoWidth),int(self.videoHeight)),Image.Resampling.LANCZOS)
                    self.photo = ImageTk.PhotoImage(image = self.tempImage)
                    self.VideoCanvas[i].create_image(0, 0, image = self.photo, anchor = tk.NW)
                    if len(self.BBox) == 0:
                        self.BBox.append(self.VideoCanvas[i].create_rectangle(self.xVar.get() - 5,self.yVar.get()-5,self.xVar.get() 5,self.yVar.get() 5))
                    else:
                        self.VideoCanvas[i].coords(self.BBox[0],self.xVar.get() - 5,self.yVar.get()-5,self.xVar.get() 5,self.yVar.get() 5)

xVar and yVar are the linked IntVar for the sliders, i'm trying to make it somewhat scalable so it's a bit messy

CodePudding user response:

You can use the methods tag_lower and tag_raise to change the stacking order of objects on a canvas.

Here's a contrived example:

import tkinter as tk

def do_raise():
    canvas.tag_raise("square")

def do_lower():
    canvas.tag_lower("square")

root = tk.Tk()
toolbar = tk.Frame(root)
canvas = tk.Canvas(root, width=400, height=400, background="black")

toolbar.pack(side="top", fill="x")
canvas.pack(side="bottom", fill="both", expand=True)

raise_button = tk.Button(toolbar, text="Raise", command=do_raise)
lower_button = tk.Button(toolbar, text="Lower", command=do_lower)

raise_button.pack(side="left")
lower_button.pack(side="left")

canvas.create_rectangle(100, 100, 200, 200, fill="red", tags=("square",))
canvas.create_oval(150, 150, 250, 250, fill="white", tags=("circle",))
root.mainloop()

screenshot, square behind circle screenshot, circle behind square

  • Related