0
votes

I'm new to stack exchange and am inexperienced with python. I am using python3 and have used SourceFileLoader from importlib.machinery to run another script(which uses tkinter) from my main script. This initially caused an error covered in this question: tkinter.TclError: image "pyimage3" doesn't exist

The solution worked for me in resolving the error, and now the child script runs as intended, except that using the Toplevel() function now also causes the app to create an empty root window - Tk() which I want to hide. I have looked at a number questions' solutions that have not worked: How do I get rid of Python Tkinter root window?
Hide the root window when a Toplevel window is opened and make it reappear when the Toplevel is destroyed

Here is a sample of my code:

from tkinter import *
from PIL import ImageTk
from importlib.machinery import SourceFileLoader

root = Toplevel()
background = Tk()
...
def Puzzle5():
    root.overrideredirect(1)
    frame = Frame(root, width=320, height=160, borderwidth=2, relief=RAISED)
    frame.pack_propagate(False)
    frame.pack(side=TOP)
    frame1 = Frame(root, width=500, height=150, borderwidth=2, relief=RAISED)
    frame1.pack_propagate(False)
    frame1.pack(side=BOTTOM)

    image = ImageTk.PhotoImage(file="/home/pi/Media/arrowup.png")
    image1 = ImageTk.PhotoImage(file="/home/pi/Media/arrowdown.png")
...
    background.withdraw()('0x0+0+0')

    root.geometry('644x450+150+50')
    root.mainloop()

def close():
    root.destroy()
    background.destroy()

Puzzle5()
1
PS. the withdraw() function doesnt work here. - M Lankester
Should you be calling the withdraw() function on root rather than the background? - DanWheeler
You do notice that you have root = Toplevel() as opposed to the questions you refer's root = Tk(). So your question comes down to this, do you want to hide the Tk widget or Toplevel widget? - Nae
I am assuming by root you actually mean the instance of the class Tk, which is background where as root is an instance of Toplevel in the code you've provided. At either rate the withdraw is supposed to hide either and iconify & deiconify is supposed to show either. Also at any rate the questions you linked supposed to be answering your question. - Nae

1 Answers

2
votes

Widgets exist in a hierarchy. At the top of that hierarchy is the root window. For any tkinter widget to exist, there must first be a root window.

You can create the root window by creating an instance of Tk. If you do not, then the first time you create a window a root window will be created for you.

Now, consider this code:

root = Toplevel()
background = Tk()

Toplevel is not a root window. For it to exist, there must first be a root window. Since you did not create one, tkinter will create one for you. So, you get a root window, and then you get the instance of Toplevel.

Then you create another root window with the second line, resulting in three windows. Even when you hide background with background.withdraw(), you still have the original root window visible.

The simple solution is to reverse those two lines of code. Create the root window first, and the Toplevel second. Then you only have a single root window, and you can hide it if you wish. However, as the answer to How do I get rid of Python Tkinter root window? explains, an even better solution is to not use a Toplevel at all, but instead put your widgets in root.