Toplevel widgets in Tkinter - python

I have a Toplevel widget I'd like it so that it would never appear within the confines of the main Tk window. Basically so that when the Toplevel appears it doesn't cover up any of the main Tk window.

You want to use wm_geometry and a tiny bit of math to calculate and set a suitable starting position for the second toplevel.

You could just set up a separate toplevel, cf:
self.newwindow = Toplevel(self)
self.newwindow.title('New Window')
and then embed the widget in the separate toplevel.

Related

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.

How to set ‘in' attribute in ' pack' method (tkinter library)?

from tkinter import *
window=Tk()
Button(window,text='').pack(in=?)
How to set 'in' attribute in pack method? what does that mean?
I looked at the source code of the pack, but I still couldn't understand how to set the ’in' attribute about pack method.
How to set 'in' attribute in pack method?
You must use in_ rather than in. For example:
root = tk.Tk()
frame = tk.Frame(root)
button = tk.Button(root)
button.pack(in_=frame)
what does that mean?
When laying out a widget, every widget except the root window has a master -- some other widget which contains the widget and which controls how it is laid out. By default the master is the same as the parent. For example, if you do Button(window,text=''), the parent of the button is window, and thus its master will also default to window.
You can use in_ to change the master. For example, you could make a button be the child of the root window, but be laid out in some other frame. In the earlier example, the button is a child of the root window but will be a slave inside of the frame.
This is something you almost never need to do with tkinter, since it's usually preferable to have the parent and the master be the same widget.

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?

Tkinter set geometry of Toplevel before displaying

I'm trying to create a Toplevel window that appears beside one of my other windows, but i'm having trouble figuring out how to set the location of the window before it is displayed. It's a simple couple lines:
histogram_window = Toplevel(self)
histogram_window.geometry('+%d+%d' % (self.__root.winfo_rootx() + self.winfo_x()*2,
self.__root.winfo_rooty()))
histogram_window.transient(self.__root)
But the window will first appear, then quickly move to the location I specified. How can I simply make it appear in the location I specified?
I've found the issue thanks to a reminder from Bryan Oakley, the problem was that upon the creation of the class I bound a matplotlib canvas to the screen and packed the widget, then tried to create a Toplevel window at the same time. I fixed this by calling the update() function for my window
Class some(Toplevel):
def __init__(self, root):
Toplevel(self, root)
# created widget
# pack widget
self.read()
def read(self):
hist = Toplevel(self)
hist.geometry(...)
hist.update() #fixed the issue

Tkinter Geometry Return to Normal

I have a tkinter window which I am able to make fullscreen, using geometry(width+height) and overrideredirect(True), but now when I return the window back to a normal size and execute the command overrideredirect(False), I cannot seem to get the window to automatically follow the size of the widgets inside it, as it would do had I not changed the size. Do you know any way which I could return the window to automatically following the size of the widgets again? Thank You in Advance!
Call the geometry with a value of "" to get it to reset itself to its natural size.
Tkinter is based on tk, and the tk docs say this on the matter:
If newGeometry is specified as an empty string then any existing
user-specified geometry for window is cancelled, and the window will
revert to the size requested internally by its widgets.
I believe you're looking for the winfo_reqwidth/reqheight() methods. These return the required width and height for all the widgets that are children of the widget they're called on. Just plug those into the geometry() method the same way you did to go fullscreen on your restore function, like this:
def fullscreen():
root.overrideredirect(True)
root.geometry('{0}x{1}+0+0'.format(root.winfo_screenwidth(), root.winfo_screenheight()))
def restore():
root.overrideredirect(False)
root.geometry('{0}x{1}'.format(root.winfo_reqwidth(), root.winfo_reqheight()))
root = Tk()
Button(root, text='Full Screen', command=fullscreen).pack()
Button(root, text='Restore', command=restore).pack()
root.mainloop()

Categories