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

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

Related

How do I execute a code within a tk.Toplevel()

I'm somewhat new to python (started in Nov.) and after complete my first "program" I'm trying to built the GUI using Tkinter. I want to put the program on a Toplevel that I've created and have it run, but all Tkinter tutorials only talk about widgets and I don't know how to specify that a code should run on a specific Toplevel window. The best I can figure is to run the in the section where I define the Toplevel as shown in the example below, but that is not working.
from tkinter import *
import tkinter as tk
root=Tk()
root.geometry("500x200")
root.title('Test')
Label(root, text="Test").pack()
def test():
gen_win = Toplevel(root)
gen_win.title("Test")
gen_win.geometry("500x500")
Label(gen_win, text="Test").pack()
print(2+2)
btn_test=tk.Button(root, text="test", command=test).pack(fill=tk.X)
root.mainloop()
The example program (print(2+2)) doesn't print on the toplevel. Any ideas?
#jasonharper gave the correct answer:
"Code doesn't "run on a specific Toplevel window". It just runs, and if it happens to create a widget, or modify the contents of an existing widget, that change becomes visible as soon as your code returns to the mainloop. Label(gen_win, text=str(2+2)).pack() would be the simplest way to make your addition results visible in the window."

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

How to duplicate Tkinter pop-up

So the code initially begins with a pop up asking you if you are ready, then once you select yes, a pop-up appears and if you try and close it, it will duplicate itself. Right now, it cannot duplicate itself.
Sorry if code is bad and riddled with mistakes (I'm just a beginner.) Thanks for helping.
from tkinter import *
from tkinter import messagebox
def a():
window2 = Tk()
offset = 300 + 1*10
window2.geometry('250x50+'+str(offset)+'+'+str(offset))
window2.title('')
window2.resizable(False, False)
la = Label(window2,text = 'ccmeockeoowpeokv.').pack()
button = Button(window2, text = 'OK', command = a()).pack()
def begining():
window = Tk()
window.eval('tk::PlaceWindow %s center' %window.winfo_toplevel())
window.withdraw()
if messagebox.askyesno("heh", "Ready?.") == True:
a()
window.deiconify()
window.destroy()
window.quit()
begining()
Do NOT ever insert Tk() if there are the absolute root of application, because it's just gonna make a new App, and NOT a new Window
The only method is using Toplevel()
Here, i explain you a bit
What is Toplevel()?
The Toplevel() widget is used to create and display the toplevel windows which are directly managed by the window manager
What is the function of Toplevel()?
The function of Toplevel() is to create a new window, without using Tk(). The Tk() and Toplevel() is almost same, but Toplevel() is to create a new window, without even create new application, if you watch some tutorial, the Tk() function is used to be creating a new application
What is the difference between Toplevel() and Tk()?
Tk() is the absolute root of the application, it is the first widget that needs to be instantiated and the GUI will shut down when it is destroyed. Toplevel() is a window in the application, closing the window will destroy all children widgets placed on that window but will not shut down the program
I suggest you to read more of the docs, or watch some tkinter tutorials on Youtube
Happy coding!

Python 3 tkinter: focus_force on messagebox

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!

Adding Tix Widget to Tkinter Container

I'm working with Tkinter in Python 2.7 on Windows 7, and found the need to create a popup box with a tree-style list of checkboxes. I could not find this in Tkinter, or ttk. I did, however, find it in Tix in the CheckList widget. I got a working standalone example using Tix, but I cannot figure out how to add my Tix.CheckList to my ttk.Frame that controls my main program.
Surely I am not forced to use Tix framework from the ground up?
import Tix
import pandas as pd
import Tkinter as tk
class TreeCheckList(object):
def __init__(self, root):
self.root = root
self.cl = Tix.CheckList(self.root)
self.cl.pack(fill=Tix.BOTH, expand=Tix.YES)
self.cl.hlist.config(bg='white', bd=0, selectmode='none', selectbackground='white', selectforeground='black', drawbranch=True, pady=5)
self.cl.hlist.add('ALL', text='All Messages')
self.cl.hlist.add('ALL.First', text='First')
self.cl.setstatus('ALL.First', "off")
self.cl.hlist.add('ALL.Second', text='Second')
self.cl.setstatus('ALL.Second', "off")
self.cl.autosetmode()
def main():
root = Tix.Tk()
top = Tix.Toplevel(root)
checklist = TreeCheckList(top)
root.update()
top.tkraise()
root.mainloop()
if __name__ == '__main__':
main()
The above code works in a standalone program using all Tix widgets. However, when I try to implement this into my larger program, I receive a TclError: invalid command name "tixCheckList"
To simulate this in the standalone, I changed the lines:
root = Tix.Tk()
top = Tix.Toplevel(root)
to
root = tk.Tk()
top = tk.Toplevel(root)
I was hoping I could just implement a Tix.Toplevel, placing it on a tk.Tk() root, but same issue.
Am I only allowed to use Tix frames when using a Tix widget, or am I misunderstanding something? If anyone has good Tix documentation, I would LOVE whatever I can get. It seems good docs on it are few and far between. Or is this same functionality included in ttk and I've just overlooked it? It seems to be one of the only things left out.
I have just learned that apparently only root needs to be a Tix class. Since Tk, and therefore ttk, classes appear to be added to the Tix root just fine (since most of them extend the Tkinter classes anyway), this appears to be a "fix". So my problem may have been solved by changing just
root = tk.Tk()
to
root = Tix.Tk()
This did require that I pull Tix into a part of my program I wasn't wanting for encapsulation purposes, but I guess there's no other way.

Categories

Resources