Exit a tkinter window even when unfocused - python

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()

Related

Stop Tkinter window taking focus when created

I want the tkinter window i'm creating to stop taking the program focus when it is opened but still stay on top and 'lifted' the program is simple however I cant seem to find a solution to make the window open but not take focus as im not even sure thats possible.
from tkinter import *
Window = Tk()
champ_text = Label(Window, text='hello', font="arial, 100",)
champ_text.pack()
Window.wm_attributes('-disabled', False)
Window.lift()
Window.wm_attributes("-topmost", True)
#Window.overrideredirect(True)
Window.mainloop()
Foreground = focus. In my head.
You can however decide where you want the window to open on the screen:
Window.geometry('200x200+400+400')
"200x200" is the size of the window that you open.
"+400+400" is the placement on the screen for the window.
Open the window in the foreground on the side of the screen will make it not so much in focus?

Disable window move in Tkinter Python

it seems that I was pending to continue the bombardment of questions. It this is short, Is it possible to disable the movement of the Tkinter window without deleting the top bar of this?
It would give a minimal and reproducible code, but if it did it would only be two lines, it would be useless.
Bind a event for your window,and set the window .geometry()
But now you can not revise the window size by dragging the window's border(But it can maximize the window.).
Here is an example of the code:
import tkinter
def GetWindowPos():
global X,Y
X = win.winfo_geometry().split("+")[1]
Y = win.winfo_geometry().split("+")[2]
win.bind_all('<Configure>', HoldOn)
def HoldOn(event):
win.geometry("+{}+{}".format(X,Y))
win = tkinter.Tk()
win.geometry("400x400+{}+{}".format(12,12))
tkinter.Label(win,text="Halo!").grid()
win.after(100,GetWindowPos)
win.mainloop()
I have found a method, but as you might know to achieve something, we have to lose something!
You can use:
root.overrideredirect(True) # turns off title bar
by which you wont be able to move the tkinter window and also Tkinter application won't be displayed in taskbar, but you will also lose the title bar.
but if you wish to have the title bar,
then you can create one by this link.
Or use below to make a new title bar and also be able to move it(from this answer)
def move_window(event):
root.geometry('+{0}+{1}'.format(event.x_root, event.y_root)
# bind title bar motion to the move window function
title_bar.bind('<B1-Motion>', move_window)
But still your Tkinter application won't show up in taskbar, here's a solution(from this answer):
root = tkinter.Tk()
top = tkinter.Toplevel(root)
root.attributes("-alpha",0.0) # to make root invisible
#toplevel follows root taskbar events (minimize, restore)
def onRootIconify(event): top.withdraw()
root.bind("<Unmap>", onRootIconify)
def onRootDeiconify(event): top.deiconify()
root.bind("<Map>", onRootDeiconify)
You can add a toplevel window under the root object, make toplevel invisible and then handle the icon events of top level to hide or show the root window on taskbar.

Is there any way of doing something after the Tkinter window is closed?

So I have this program which runs inside a tkinter window. The idea is that when a user finishes using the porgram their scores/info from that session is stored, so their scores should only be stored after they shut the window down.
I am wondering if there is anything which could tell the program when the user presses the close button (from the window, not an in-window widget) so that processes only happen after they close the window.
The mainloop function only ends once the root window is closed, so you can just put your code after that.
from Tkinter import *
root = Tk()
root.mainloop()
print("This message should appear after the window closes.")
I suppose you could also register a protocol handler to catch WM_DELETE_WINDOW events, but that seems like an unnecessary complication.
from Tkinter import *
def x_button_pressed():
print("This message should appear after the window closes.")
root.destroy()
root = Tk()
root.protocol("WM_DELETE_WINDOW", x_button_pressed)
root.mainloop()

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.

Toplevel in Tkinter: Prevent Two Windows from Opening

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.

Categories