0

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()
M Lankester
  • 11
  • 1
  • 1
  • PS. the withdraw() function doesnt work here. – M Lankester Dec 15 '17 at 14:24
  • Should you be calling the `withdraw()` function on `root` rather than the `background`? – DanWheeler Dec 15 '17 at 14:31
  • 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 Dec 15 '17 at 15:14
  • Possible duplicate of [How do I get rid of Python Tkinter root window?](https://stackoverflow.com/questions/1406145/how-do-i-get-rid-of-python-tkinter-root-window) – Nae Dec 15 '17 at 15:17
  • 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 Dec 15 '17 at 15:43

1 Answers1

2

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.

Bryan Oakley
  • 370,779
  • 53
  • 539
  • 685
  • Thank you Bryan, this information has completely solved the issue. As you said, calling Tk() and Toplevel() in that order created a second root window which I wasn't able to hide. – M Lankester Jan 08 '18 at 12:11