DarkLSD_GuY
DarkLSD_GuY

Reputation: 1

Make multiple tk.Toplevel windows embedded/unified in main tk window

So I'm trying to create a program which uses multiple tk.Toplevel windows. The problem with this is, that all windows show up seperated as their "own App", so when you alt tab, you switch between the toplevel windows. The pseudocode would look something like this: import tkinter as tk

top_levels = {}

def open_toplevel():
    top_level = tk.Toplevel(root)
    top_level.geometry("300x200+0+0")
    top_levels.update({f"toplevel{len(top_levels.keys())}" : top_level})

root = tk.Tk()

button = tk.Button(root, command= open_toplevel)
button.place(x=0, y=0)

root.mainloop()

So my question, is: is there a way to unify them into "one window"?

Upvotes: 0

Views: 92

Answers (1)

ss3387
ss3387

Reputation: 299

If you want all of them to unify into one window then tk.Frame is a better widget to use instead of tk.Toplevel

The purpose of tk.Toplevel is to create a new temporary window, not an extra part of the window. But frames are a really good way to organise stuff.

This code below creates new frame every time you click the button. This is just a simple example. You can also use grid for widgets in a frame. I also put a border so you can see where the frames are located.

from tkinter import *

def open_frame():
    frame = Frame(root, highlightbackground="black", highlightthickness=2)
    lbl1 = Label(frame, text=f"Frame {len(frames) + 1} label 1")
    lbl2 = Label(frame, text=f"Frame {len(frames) + 1} label 2")
    lbl1.pack()
    lbl2.pack()
    frame.pack(padx=5, pady=5)
    frames.append(frame)


root = Tk()

frames = []

btn = Button(root, text="Open Frame", command=open_frame)
btn.pack()

root.mainloop()

I hope this solution is helpful

EDIT

Use this code here to move the frames:

from tkinter import *

def open_frame():
    global frame, frames
    frame = Frame(root, highlightbackground="black", highlightthickness=2)
    lbl1 = Label(frame, text=f"Frame {len(frames) + 1} label 1")
    lbl2 = Label(frame, text=f"Frame {len(frames) + 1} label 2")
    lbl1.pack()
    lbl2.pack()
    frame.pack(padx=5, pady=5)
    frame_number = len(frames)

    lbl1.bind('<B1-Motion>', lambda event: MoveWindow(event, frame_number))
    lbl2.bind('<B1-Motion>', lambda event: MoveWindow(event, frame_number))
    frame.bind('<B1-Motion>', lambda event: MoveWindow(event, frame_number))
    
    frames.append(frame)
    labels.append(lbl1)
    labels.append(lbl2)

def MoveWindow(event, frame_number):
    global root, frames
    root.update_idletasks()
    f = frames[frame_number]
    x = f.winfo_width()/2
    y = f.winfo_height()*1.5
    f.place(x=event.x_root-x, y=event.y_root-y)

root = Tk()
root.geometry("500x500")

frames = []
labels = []

btn = Button(root, text="Open Frame", command=open_frame)
btn.pack()

root.mainloop()

Upvotes: 1

Related Questions