Toplevel in Tkinter: Prevent Two Windows from Opening - python

Say I have some simple code, like this:
from Tkinter import *
root = Tk()
app = Toplevel(root)
app.mainloop()
This opens two windows: the Toplevel(root) window and the Tk() window.
Is it possible to avoid the Tk() window (root) from opening? If so, how? I only want the toplevel. I want this to happen because I am making a program that will have multiple windows opening, which are all Toplevel's of the root.
Thanks!

The withdraw() method removes the window from the screen.
The iconify() method minimizes the window, or turns it into an icon.
The deiconify() method will redraw the window, and/or activate it.
If you choose withdraw(), make sure you've considered a new way to exit the program before testing.
e.g.
from Tkinter import * # tkinter in Python 3
root = Tk()
root.withdraw()
top = Toplevel(root)
top.protocol("WM_DELETE_WINDOW", root.destroy)
but = Button(top, text='deiconify')
but['command'] = root.deiconify
but.pack()
root.mainloop()
The protocol() method can be used to register a function that will be called when the
Toplevel window's close button is pressed. In this case we can use destroy() to exit.

Related

How to hide tkinter root window and show my image?

I have this code where I click the button and tkinter window shows an image along with a tk root window.
I tried using root.withdraw() however this just ends up creating the tkinter root window and does not display my image.. Would need help in showing the image only and hiding the tkinter root window as well
def on_click_button():
global stage
stage == 'Menu'
root = tk.Toplevel()
photoImageObj = tk.PhotoImage(file="showimg.png")
lab = tk.Label(root, image=photoImageObj).pack()
root.withdraw()
root.mainloop()
print('You clicked samsung note 20')
Tkinter sets the master attribute of a widget to be a reference to the master for that widget. Since you didn't explicitly set the master for the instance of Toplevel, master will be the root window. So, in this specific case you can call withdraw on root.master:
root.master.withdraw()
Personally, I would recommend against naming your Toplevel "root" since it's not the true root window. It makes the code a bit harder to understand since a true root window will not have a master.
You will want to provide a mechanism for showing the root window at some point, since withdrawing it will keep it alive but not visible.

How do you close all Tkinter windows when specific window closes?

I have this application in Python Tkinter. There is a Python file which is a main menu. When I click an option in the main menu it imports a python file with code that makes a new window (couldn't use Toplevel for the new window for some reasons). So when I close the main menu it should close all the other windows.
Here is my code for the main menu:
from tkinter import *
root = Tk()
root.geometry("600x600")
def newWindowImport():
import file1
def newWindowImport2():
import file2
newWindow = Button(text="new window", command=newWindowImport).pack()
newWindow2 = Button(text="new window", command=newWindowImport2).pack()
# Here is there a way so that when I exit it destroys the Main Menu as well as the opened windows
exitBtn = Button(text="Exit", command=root.destroy())
root.mainloop()
I tried the root.destroy method but it only destroys the main menu and not all the windows. Is there a way so that when I exit the main menu it destroys the main menu as well as the opened windows? If I were to use Toplevel - how would I use it in a separate file?
I am assuming that your other scripts have individual instances of Tk(), their own mainloop() and are not under a function, if that is the case, you can have all the code in your files under a function and use Toplevel(), example, file1 should look like
def something():
window=Toplevel()
#Rest of the code
And similarly file2, after that in your main program you could do something like this
from tkinter import *
import file1, file2
root = Tk()
root.geometry("600x600")
def newWindowImport():
file1.something()
def newWindowImport2():
file2.something()
newWindow = Button(text="new window", command=newWindowImport)
newWindow.pack()
newWindow2 = Button(text="new window", command=newWindowImport2)
newWindow2.pack()
# Here is there a way so that when I exit it destroys the Main Menu as well as the opened windows
exitBtn = Button(text="Exit", command=root.destroy)
root.mainloop()
You could also let go of the functions and make these changes to have it shorter
newWindow = Button(text="new window", command=file1.something)
newWindow.pack()
newWindow2 = Button(text="new window", command=file2.something)
newWindow2.pack()
The reason for your approach not working would be that each file had it's own mainloop() and hence they couldn't be destroyed when you called root.destroy in the main code.
Also note that I have removed the parentheses () from the command=root.destroy otherwise the it will be called as soon as the program initializes.
EDIT : As also suggested by #martineau in the comments, it's better to use .pack() on the Button instances separately as it provides more flexibility in using the instance later in the program, as opposed to having them hold the value None which is the return from .pack()
Using Toplevel is the correct way to do this, you need to find out why that is not working and correct it. If you did that this question would solve itself. Also, you need to remove the () from the command, it should be like this:
exitBtn = Button(text="Exit", command=root.destroy)

Exit a tkinter window even when unfocused

I am making an AI that beats the game Whac-A-Mole. This program takes over the mouse and therefore I need to make a way to stop the program from running (you can barely move the mouse, so pressing a button in Tkinter won't work). I settled on the 'Escape' key as the switch to turn it off. The problem is, whenever the AI whacks a mole (clicks on the screen), the Tkinter window becomes unfocused, therefore 'bind' doesn't work.
Is there a way of stopping the program without the Tkinter window being focused?
If you want the window to focus, you can use the .focus() method.
For example:
from tkinter import *
window = Tk()
window2 = Toplevel()
window.mainloop()
The second window, window2 won't be in focus. To put it in focus, you can do this:
from tkinter import *
window = Tk()
window.title("window1")
window2 = Toplevel()
window2.title("window2")
window2.focus()
window.mainloop()
This will bring the window2 into focus, even though on the bottom.
To bring it to the top, you can add this line:
window2.attributes("-topmost", True)
Hope this helps!
To bring the tkinter window on the top all other window you can use :
from tkinter import*
gui = Tk()
gui.wm_attributes("-topmost", True)
gui.mainloop()

How to remove title bar in Tkinter program?

I am working on a project using Tkinter library for making a GUI. This GUI will be displayed on a touch screen using raspberry pi 3.
I want to prevent user from exiting or minimising the program.
Is there any way to disable or remove the title bar? Or is there a better way to achieve this?
Since you mentioned a raspberry pi I suppose you are using Linux. In this case you can use root.attributes('-type', 'dock') (assuming your Tk instance is called root). This way, your window will have no decoration (so no close or minimize buttons) and will be always on top. If you don't want it always on top, you can use type 'splash' instead. In any case, you will need to use focus_force to be able to get keyboard focus.
import tkinter as tk
root = tk.Tk()
root.attributes('-type', 'dock')
root.geometry('200x200')
tk.Entry(root).pack()
root.focus_force()
root.mainloop()
Otherwise, you can prevent the window from being closed by setting the 'WM_DELETE_WINDOW' protocol and redisplay the window each time it is minimized:
import tkinter as tk
root = tk.Tk()
def unmap(event):
if event.widget is root:
root.deiconify()
root.protocol('WM_DELETE_WINDOW', lambda: None) # prevent closing
root.bind('<Unmap>', unmap) # redisplay window when it's minimized
root.mainloop()
root = tk.Tk()
root.wm_attributes('-type', 'splash')
For more details go to this link: Remove titlebar without overrideredirect() using Tkinter?

How to show a window that was hidden using "withdraw" method?

I would like to show a window after I called withdraw.
The following is my current code:
from Tkinter import *
def callback():
global root
root.withdraw()
win2 = Tk()
root = Tk()
Label(root,text='this is a window').pack()
Button(root,text='withdraw',command=self.callback).pack()
mainloop()
As soon as I press the button, the window disappears much as I want it, and another window appears and everything works great. How do I get the first window back, in the same state as it was before?
Use the following commands when you want to show the window:
# root.update() # not required
root.deiconify()
If you want to know more about it, see here.

Categories