Skip to content
Advertisement

tkinter – dock and undock frame with wm_manage and wm_forget

I found the following in the tk docs:

The wm manage and wm forget commands may be used to perform undocking and docking of windows.

So I tried wm_manage and wm_forget in this code:

import tkinter as tk

root = tk.Tk()

class MyFigure(tk.Frame):
    def __init__(self, master):
        tk.Frame.__init__(self,master)
        self.master = master
        self.bc = tk.Button(self, text='confi',
                            command=lambda:self.configure(bg='red')
                            )
        self.bmanage = tk.Button(self, text='manage',
                                 command = lambda:self.master.wm_manage(self)
                                 )
        self.bforget = tk.Button(self, text='forget',
                                 command = lambda:self.master.wm_forget(self)
                                 )

        self.bmanage.pack(side='left')
        self.bc.pack(side='left')
        self.bforget.pack(side='left')

mf = MyFigure(root)
mf.pack()
root.mainloop() 

But it dosen’t worked out. So I readed more and there is no way I can missunderstand this:

A toplevel widget may be used as a frame and managed with any of the other geometry managers after using the wm forget command.

So I tried to do something like that:

def _manage(self):
    top = self.master.wm_manage(self)
    print(top)
def _forget(self):
    frame = self.master.wm_forget(self)
    print(frame)

But both return None. Am I something missing here? What am I doing wrong?

Advertisement

Answer

In order to make wm_forget correctly work, you should pass a toplevel window as argument. For instance, if you add the following lines in the constructor of the class:

self.top = tk.Toplevel()
self.top.title("Top level")

You can then call the method as follows:

self.master.wm_forget(self.top)

Regarding the wm_manage, you should pass as argument the widget you want to convert to a stand alone top-level window. Please keep in mind that you can only use this command with frame, labelframe and toplevel widgets. If you apply this command to your main window Tk, nothing will happen.

A full example converting a frame to a toplevel (pressing button manage) and converting it back to frame (pressing button forget):

import tkinter as tk

root = tk.Tk()

class MyFigure(tk.Frame):
    def __init__(self, master):
        tk.Frame.__init__(self,master)
        self.master = master
        self.bc = tk.Button(self, text='confi',
                            command=lambda:self.configure(bg='red')
                            )
        self.bmanage = tk.Button(self, text='manage',
                                 command = lambda:self._manage()
                                 )
        self.bforget = tk.Button(self, text='forget',
                                 command = lambda:self._forget()
                                 )

        self.bmanage.pack(side='left')
        self.bc.pack(side='left')
        self.bforget.pack(side='left')
        self.frame = tk.Frame(self.master, bg="red", height=100)
        self.label=tk.Label(self.frame, text="hi")
        self.frame.pack()
        self.label.pack(expand=True, fill=tk.BOTH)

    def _manage(self):
        test=self.master.wm_manage(self.frame)

    def _forget(self):
        self.master.wm_forget(self.frame)
        self.frame.pack()

mf = MyFigure(root)
mf.pack()
root.mainloop() 

User contributions licensed under: CC BY-SA
10 People found this is helpful
Advertisement