Python 3 tkinter: focus_force on messagebox - python

I'm running python 3 code in background which should show a popup window in some situations. I'm using tkinter for this:
import tkinter as tk
from tkinter import messagebox
def popup(message, title=None):
root = tk.Tk()
root.withdraw()
root.wm_attributes("-topmost", 1)
messagebox.showinfo(title, message, parent=root)
root.destroy()
popup('foo')
The ok-button in this infobox should get the focus automatically when popping up. Sadly I'm not able to do this. I tried root.focus(), but it does not help. Any ideas how to solve that? TIA
BTW: The code should be platform independent (Linux and Windows).
Edit:
Maybe I missunderstood the focus keyword and I should clarify my question:
root = tk.Tk()
root.focus_force()
root.wait_window()
When calling the code above the root window is active, even if I worked in e.g. the browser before. Is this also possible for messagebox.showinfo? Adding root.focus_force() in the popup function does not help.
Is this even possible? Or is it necessary to create my own root window? I really like the appearance of the messagebox with the icon.
Edit 2:
Here is a video: https://filebin.net/no195o9rjy3qq5c4/focus.mp4
The editor is the active window, even after the popup was shown.
In Linux I it works as expected.

You can use the default argument in the messagebox function.
default constant
Which button to make default: ABORT, RETRY, IGNORE, OK, CANCEL, YES, or NO (the constants are defined in the tkMessageBox module).
So, here is an example to highlight the "ok" button.
import tkinter as tk
from tkinter import messagebox
def popup(message, title=None):
root = tk.Tk()
root.withdraw()
messagebox.showinfo(title, message, parent=root, default = "ok")
root.destroy()
popup('foo')
Hope this helps!

Related

new tkinter window loses focus after mainloop ends

I'm using the following code to create a window after destroying another.
from tkinter import *
tk=Tk()
def destroy():
tk.destroy()
tk.after(2000,destroy)
tk.mainloop()
tk=Tk()
tk.mainloop()
The window is created alright, but it loses focus. I tried lift() and focus() methods with no result.
You can use <tk.Tk>.focus_force() to force the window to be focused.
So your modified code will look like this:
from tkinter import *
tk = Tk()
def destroy():
tk.destroy()
tk.after(2000, destroy)
tk.mainloop()
tk = Tk()
tk.focus_force()
tk.mainloop()
Although it is much better to reuse the window. Destroy all of the widgets on the window and reuse it instead of destroying and recreating it. Creating a window takes a lot of resources.
Also something else: the variable tk is usually used for something else so please don't use it for tkinter windows. Usually people use root or window for windows.
Force the input focus to the widget using focus_force(). Just update you last part.
tk=Tk()
tk.focus_force()
tk.mainloop()
Also, You can make a Toplevel() which is basically just creating a new window over the root window.
from tkinter import *
tkk=Tk()
tkk.withdraw()
tk=Toplevel()
def destroy():
tk.destroy()
tkk.deiconify()
tk.after(2000,destroy)
tk.focus_force()
tkk.mainloop()

Tkinter simpledialog boxes not getting focus in Windows 10 with Python3

In the code below, the first dialog box gets focus immediately, so the user can just type an answer and press enter. In the second one, that doesn't seem to happen when running in Windows. Running Raspbian 9, both windows get focus when they open.
Is there any way I can get both windows to get focus when they open in Windows?
import tkinter as tk
from tkinter import simpledialog
root = tk.Tk()
root.withdraw()
answer1 = simpledialog.askstring("Test1","This one gets focus when it opens",parent=root)
answer2 = simpledialog.askstring("Test2","This one doesn't",parent=root)
I have watched this question for a few days now hoping someone might shed some light on this issue. I'm running Python 3.6.5 under windows 10 and get the same problem.
I have tried several different things but it seems Microsoft does things their own way. I have finally found a thing that works, but only if you don't hide the root window:
import tkinter as tk
from tkinter import simpledialog
root = tk.Tk()
#root.withdraw() # This does not work if you hide the root window
root.update_idletasks()
answer1 = simpledialog.askstring("Test1","This one gets focus",parent=root)
root.update_idletasks()
answer2 = simpledialog.askstring("Test2","This one doesn't",parent=root)
I found the following worked (with a small flicker of the root window on destroy()):
root = tk.Tk()
root.withdraw()
filename = filedialog.askopenfilename()
root.deiconify()
root.destroy()

Python: How to close the previous Main (top) tkinter windows

I want my script should work in such a way that, close all the previous windows in tkinter.
If I minimise the existing pop up window and again I will run same script, it will again pop up new window. How can I close the already existing window, when i run script again?
Simple code:
import Tkinter as tk
root = tk.Tk()
root.mainloop()
Maybe if you check all variable in locals and see if you have tk type in it?
import tkinter as tk
root = tk.Tk()
tk_type = type(root)
print(tk_type)
var=0
for var in locals().items():
if type(var[1]) == tk_type:
print(var, 'to be deleted')
root.mainloop()
something like this where you can put the test at the begining of the class to see if it exists other TK window object.
I'm sure it should exist a better solution though.

tkinter messagebox always appears behind main pygame window

I am trying to make my messagebox appear in front of my pygame window, but it keeps appearing behind it. Here's my code:
from tkinter import messagebox
# pygame loop here
messagebox.showinfo("Title", "Message here")
Do I need to do add some lines of code to bring it to the front? Any help would be appreciated.
I got it to work. I had to add root.withdraw() as well.
import tkinter as tk
from tkinter import messagebox
root = tk.Tk()
root.withdraw()
# pygame loop here
messagebox.showinfo("Title", "Message here")
root.lift()
Not sure why hiding the root tkinter window makes it work...
This will put the window in the middle of the screen on the top level of everything, so it will not be hidden behind and stays in front.
window = Tk()
window.eval('tk::PlaceWindow %s center' % window.winfo_toplevel())

How to make Toplevel() widget appear above main root window?

I have made a Toplevel widget but when it pops up it always appears below my root window. Is there an easy way I can make it come to the top most level when it pops up?
you can use the .lift() method on a Toplevel widget:
import tkinter
root = tkinter.Tk()
root.title("root")
top = tkinter.Toplevel(root)
top.title("top")
top.lift(root)
root.mainloop()
according to this documentation you should be able to just use top.lift() to raise above all other windows but it didn't seem to work for me.
Edit: calling top.lift() without arguments does work when called during the mainloop, although since this question was specifically when starting the program that isn't very useful.
try attributes
import tkinter
root = tkinter.Tk()
root.title("root")
top = tkinter.Toplevel(root)
top.attributes('-topmost', 'true')
top.title("top")
root.mainloop()

Categories

Resources