python tkinter restore window without title bar - python

I have a tkinter window that I removed the title bar from and added a custom close and minimize button to. When the program first loads it doesn't display an icon to the taskbar. When I click the custom made minimize button it then creates an icon on the taskbar; however, when I click to restore the window I am unable to get rid of the titlebar again.
I want the icon to always show on the taskbar, and when the program is minimized and then restored I would like the title bar to still be gone from .overrideredirect(1). Unfortunately I'm having trouble resetting the flag before and after minimizing without making the taskbar icon disappear.
Please let me know what I am doing wrong. Thanks!
#!/usr/bin/python3
from tkinter import *
import tkinter as tk
import datetime
import time
import math
root = tk.Tk()
root.overrideredirect(1)
def close():
root.destroy()
def minimizeWindow():
root.withdraw()
root.overrideredirect(False)
root.iconify()
root.resizable(False, False)
canvas = Canvas(root, width = 400, height = 400)
canvas.pack()
exit = Button(root, text='x', command = close)
exitWindow = canvas.create_window(10,10, window=exit)
minimize = Button(root, text='-', command = minimizeWindow)
minimizeWindow = canvas.create_window(30,10,window=minimize)
icon = PhotoImage(file='py.gif')
root.tk.call('wm', 'iconphoto', root._w, icon)
root.mainloop() # starts the mainloop
I am trying to make it work for both windows and linux. The reason I'm taking out the title bar altogether is to avoid the differences that come from the OS font and window settings. It's currently exhibiting this same behavior on both Operating Systems.
To reiterate, I want the taskbar icon to show up on program launch and I want the program's window to maintain it's titlebar-less state when restored from being minimized.

It depends on what operating system you are using. If you are using Windows the below solution should work for you.
I have added a function that will reapply the overriderdirect. This function is being called by a bind we used on root.
I have also changed your canvas to a frame as this make it easier to manage things like buttons.
For linux you may need to use a different file type. On window you use .ico and on linux you may need to use .xbm.
See this answer about it on this post: Python 3 tkinter iconbitmap error in ubuntu
Update:
I have added the iconbitmap and root.tk.call('wm', 'iconphoto', root._w, icon) however I am not sure if you will be able to make your taskbar icon change until you compile the code at least in windows. You can use py2exe or freeze. I have used freeze before and I have a customer desktop and taskbar icon I use for it.
import tkinter as tk
root = tk.Tk()
root.geometry("400x400")
root.overrideredirect(1)
root.resizable(False, False)
root.columnconfigure(0, weight=1)
root.iconbitmap(default='./Colors/small_red.ico')
def close():
root.destroy()
def minimizeWindow():
root.withdraw()
root.overrideredirect(False)
root.iconify()
def check_map(event): # apply override on deiconify.
if str(event) == "<Map event>":
root.overrideredirect(1)
print ('Deiconified', event)
else:
print ('Iconified', event)
bar_frame = tk.Frame(root)
bar_frame.grid(row=0, column=0, sticky="ew")
bar_frame.columnconfigure(0, weight=1)
icon = tk.PhotoImage(file='./Colors/small_red.gif')
# This appears to have the same results so not sure what the difference is from iconbitmap.
# root.tk.call('wm', 'iconphoto', root._w, icon)
tk.Button(bar_frame, text='x', command=close).grid(row=0, column=1)
tk.Button(bar_frame, text='-', command=minimizeWindow).grid(row=0, column=2)
root.bind('<Map>', check_map) # added bindings to pass windows status to function
root.bind('<Unmap>', check_map)
root.mainloop()

There Are Two Ways
If you want to restore it in a new/custom Taskbar Just do this:-
from tkinter import *
import tkinter as tk
import datetime
import time
import math
root = tk.Tk()
def close():
root.destroy()
def minimizeWindow():
root.update_idletasks()
root.overrideredirect(False)
root.state('iconic')
root.attributes('-topmost', True)
root.overrideredirect(True)
root.geometry("215x330")
root.wm_overrideredirect(True)
root.attributes('-topmost', False)
root.resizable(False, False)
canvas = Canvas(root, width = 400, height = 400)
canvas.pack()
exit = Button(root, text='x', command = close)
exitWindow = canvas.create_window(10,10, window=exit)
minimize = Button(root, text='-', command = minimizeWindow)
minimizeWindow = canvas.create_window(30,10,window=minimize)
icon = PhotoImage(file='py.gif')
root.tk.call('wm', 'iconphoto', root._w, icon)
root.mainloop()
Else if you want to restore in your windows Taskbar:-
from tkinter import *
import tkinter as tk
import datetime
import time
import math
root = tk.Tk()
root.overrideredirect(1)
def check(event):
if str(event) == "<Map event>":
window.overrideredirect(1)
else:
None
def close():
root.destroy()
def minimizeWindow():
root.withdraw()
root.overrideredirect(False)
root.iconify()
root.overrideredirect(True)
root.resizable(False, False)
canvas = Canvas(root, width = 400, height = 400)
canvas.pack()
exit = Button(root, text='x', command = close)
exitWindow = canvas.create_window(10,10, window=exit)
minimize = Button(root, text='-', command = minimizeWindow)
minimizeWindow = canvas.create_window(30,10,window=minimize)
icon = PhotoImage(file='py.gif')
root.tk.call('wm', 'iconphoto', root._w, icon)
root.bind('<Map>', check_map)
root.bind('<Unmap>', check_map)
root.mainloop() # starts the mainloop

Related

Tkinter overrideredirect not working in Mac OS X

I'm using the latest version of Mac OS, and Python 3.9. I tried using the overrideredirect to delete the title bar and add my own. However, the result does not show the window. The app is seen in the dock, and the menu bar. But it is not displayed.
My code:
from tkinter import *
root = Tk()
def move_window(event):
root.geometry('+{0}+{1}'.format(event.x_root, event.y_root))
root.overrideredirect(True)
root.geometry('400x100+200+200')
title_bar = Frame(root, bg='white', relief='raised', bd=2)
close_button = Button(title_bar, text='X', command=root.destroy)
window = Canvas(root, bg='black')
title_bar.pack(expand=1, fill=X)
close_button.pack(side=RIGHT)
window.pack(expand=1, fill=BOTH)
title_bar.bind('<B1-Motion>', move_window)
root.mainloop()
The same code works well in windows.
Thanks in advance! :)
On Macs, we need two calls of overrideredirect to remove the border.
Do it like this:
root.overrideredirect(False)
root.overrideredirect(True)
But note that certain events might fail to bind properly, per this post

How do I remove the title bar with tkinter on linux LXDE without overrideredirect or attributes?

[my previous post was closed stating it was a duplicate but I still do not have an answer]
I am trying to create a window without a title bar that has buttons on it. These buttons would open/run certain programs (open web browser, reboot computer, etc). I want this window to remain on the screen always and not able to be closed (like a kiosk with buttons on the screen).
On windows, I am able to make this work fine with overrideredirect(True) and attributes("-topmost", True). However, when I run the program on a raspberry pi with LXDE, it doesn't recognize the overrideredirect(True). I have tried changing True to 1 and still no success. I am unable to find anything about this for LXDE specifically. Is it not possible since my window manager is not responding to this argument? Maybe there is another way to accomplish what I am trying to do.
I also tried the attributes('-type', 'splash') and attributes('-type', 'dock') without success.
import tkinter as tk
import webbrowser
root = tk.Tk()
#URL to open when Browser button
browser_url = 'http://www.google.com'
class Application(tk.Frame):
def __init__(self, master=None):
super().__init__(master)
self.master = master
self.pack(fill=tk.BOTH, expand=1, pady=20)
self.create_widgets()
def create_widgets(self):
self.browser = tk.Button(self, height=2, width=10)
self.browser["text"] = "Browser"
self.browser["command"] = self.browser_go
self.browser.pack(side="left", padx=25)
def browser_go(self):
webbrowser.open_new(browser_url)
root.geometry('2160x100+0+0') #Window size (x,y) and location (x,y)
root.resizable(False, False) #Window not resizeable
root.update_idletasks()
root.overrideredirect(True) #Prevent ability to close the windows
root.attributes("-topmost", True) #Window on top always of other windows
app = Application(master=root)
app.mainloop()
Your code works for me on Linux Mint 19.2 with Gnome if I remove
root.update_idletasks()
or if I use it after root.overrideredirect(True)
Maybe it will works also for your system.
import tkinter as tk
import webbrowser
root = tk.Tk()
#URL to open when Browser button
browser_url = 'http://www.google.com'
class Application(tk.Frame):
def __init__(self, master=None):
super().__init__(master)
self.master = master
self.pack(fill=tk.BOTH, expand=1, pady=20)
self.create_widgets()
def create_widgets(self):
self.browser = tk.Button(self, height=2, width=10)
self.browser["text"] = "Browser"
self.browser["command"] = self.browser_go
self.browser.pack(side="left", padx=25)
def browser_go(self):
webbrowser.open_new(browser_url)
root.geometry('2160x100+0+0') #Window size (x,y) and location (x,y)
root.resizable(False, False) #Window not resizeable
root.overrideredirect(True) #Prevent ability to close the windows
#root.update_idletasks() # has to be after root.overrideredirect(True)
root.attributes("-topmost", True) #Window on top always of other windows
app = Application(master=root)
app.mainloop()
I don't need even root.resizable(False, False) and root.attributes("-topmost", True)
root = tk.Tk()
root.geometry('2160x100+0+0') #Window size (x,y) and location (x,y)
root.overrideredirect(True) #Prevent ability to close the windows
app = Application(master=root)
app.mainloop()

python tkinter clicking on button to open new window

I've made 3 buttons on my window. I choosed that the main window should have a specific background image and a full screen.
Now there is a problem. I would like to move to a new window (page) (with an other background and other things) by clicking on button 3.
Things i tryd:
from Main.Info.travelhistry import *
I've added this to the main window to open a new python file with the code of the second screen that has to open when clicking on button 3. But I found out that if I do this both windows will open when running main window.
I added root1 = Tk() at the beginning, root1.mainloop() at the end and between them the code for the other window. But this won't work also, its opening 2 windows like above.
Those were all my attempts and i cant figure out a better way. I can but the background would stay the same. But I have to change the background for the new window to a background image i made...
Any idea what im doing wrong?
from tkinter import *
from tkinter.messagebox import showinfo
from Main.Info.travelhistry import *
def clicked1():
bericht = 'Deze functie is uitgeschakeld.'
showinfo(title='popup', message=bericht)
root = Tk()
a = root.wm_attributes('-fullscreen', 1)
#Hoofdmenu achtergrond
C = Canvas(root, bg="blue", height=250, width=300)
filename = PhotoImage(file = "test1.png")
background_label = Label(root, image=filename)
background_label.place(x=0, y=0, relwidth=1, relheight=1)
C.pack()
# Geen OV-chipkaart button
b=Button(master=root, command=clicked1)
photo=PhotoImage(file="button1.png")
b.config(image=photo,width="136",height="53", background='black')
b.place(x=310, y=340)
#Buitenland button
b2=Button(master=root, command=clicked1)
photo1=PhotoImage(file="button2.png")
b2.config(image=photo1,width="136",height="53", background='black')
b2.place(x=490, y=340)
#Reis informatie
b3=Button(master=root)
photo2=PhotoImage(file="button3.png")
b3.config(image=photo2,width="136",height="53", background='black')
b3.place(x=680, y=340)
root.mainloop()
root2.mainloop()
You shouldn't call more than one Tk() window.
Instead, tkinter has another widget called Toplevel which can be used to generate a new window.
See below for an example:
from tkinter import *
root = Tk()
def command():
Toplevel(root)
button = Button(root, text="New Window", command=command)
button.pack()
root.mainloop()
This one opens new window that you can edit.
from tkinter import *
Window = Tk()
def Open():
New_Window = Tk()
#You can edit here.
New_Window.mainloop()
Btn1 = Button(text="Open", command=Open)
Bt1n.pack()
Window.mainloop()

No input possible after tk

If have this piece of code:
import Tkinter as tk
import tkFileDialog
menu = tk.Tk()
res = tkFileDialog.askopenfilename() # un-/comment this line
label = tk.Label(None, text="abc")
label.grid(row=0, column=0, sticky=tk.W)
entry = tk.Entry(None)
entry.grid(row=0, column=1, sticky=tk.EW)
res = menu.mainloop()
Note: the askopenfilename is just a dummy input. So Just close it to get to the (now blocked) main window of TK.
When I comment the askopenfilename everything works fine. But with the it, I can not enter data in the entry.
This only happens with Windoze environments. The askopenfilename seems to steal the focus for the main TK window. After clicking a totally different window and back again in the TK window, input is possible.
I've seen reports of this before, I think it's a known bug on windows. You need to let mainloop start before you open a dialog.
If you want the dialog to appear when the app first starts up you can use after or after_idle to have it run after mainloop starts up.
For example:
menu = tk.Tk()
...
def on_startup():
res = tkFileDialog.askopenfilename()
menu.after_idle(on_startup)
menu.mainloop()
If you don't want any other GUI code to execute until after the dialog, move all your code except for the creation of the root window and call to mainloop into on_startup or some other function.
For example:
def main(filename):
label = tk.Label(None, text="abc")
label.grid(row=0, column=0, sticky=tk.W)
entry = tk.Entry(None)
entry.grid(row=0, column=1, sticky=tk.EW)
def on_startup():
res = tkFileDialog.askopenfilename()
main(filename)
root = Tk()
root.after_idle(on_startup)
askopenfilenamehas it's own event loop. The programm stops, until you selected a filename, and continues afterwards.

How to snap the tkinter canvas to the top left of the screen? [duplicate]

How can I make a frame in Tkinter display in fullscreen mode? I saw this code, and it's very useful…:
>>> import Tkinter
>>> root = Tkinter.Tk()
>>> root.overrideredirect(True)
>>> root.geometry("{0}x{1}+0+0".format(root.winfo_screenwidth(), root.winfo_screenheight()))
…but is it possible to edit the code so that hitting Esc automatically makes the window "Restore down"?
I think this is what you're looking for:
Tk.attributes("-fullscreen", True) # substitute `Tk` for whatever your `Tk()` object is called
You can use wm_attributes instead of attributes, too.
Then just bind the escape key and add this to the handler:
Tk.attributes("-fullscreen", False)
An answer to another question alluded to this (with wm_attributes). So, that's how I found out. But, no one just directly went out and said it was the answer for some reason. So, I figured it was worth posting.
Here's a working example (tested on Xubuntu 14.04) that uses F11 to toggle fullscreen on and off and where escape will turn it off only:
import sys
if sys.version_info[0] == 2: # Just checking your Python version to import Tkinter properly.
from Tkinter import *
else:
from tkinter import *
class Fullscreen_Window:
def __init__(self):
self.tk = Tk()
self.tk.attributes('-zoomed', True) # This just maximizes it so we can see the window. It's nothing to do with fullscreen.
self.frame = Frame(self.tk)
self.frame.pack()
self.state = False
self.tk.bind("<F11>", self.toggle_fullscreen)
self.tk.bind("<Escape>", self.end_fullscreen)
def toggle_fullscreen(self, event=None):
self.state = not self.state # Just toggling the boolean
self.tk.attributes("-fullscreen", self.state)
return "break"
def end_fullscreen(self, event=None):
self.state = False
self.tk.attributes("-fullscreen", False)
return "break"
if __name__ == '__main__':
w = Fullscreen_Window()
w.tk.mainloop()
If you want to hide a menu, too, there are only two ways I've found to do that. One is to destroy it. The other is to make a blank menu to switch between.
self.tk.config(menu=self.blank_menu) # self.blank_menu is a Menu object
Then switch it back to your menu when you want it to show up again.
self.tk.config(menu=self.menu) # self.menu is your menu.
This creates a fullscreen window. Pressing Escape resizes the window to '200x200+0+0' by default. If you move or resize the window, Escape toggles between the current geometry and the previous geometry.
import Tkinter as tk
class FullScreenApp(object):
def __init__(self, master, **kwargs):
self.master=master
pad=3
self._geom='200x200+0+0'
master.geometry("{0}x{1}+0+0".format(
master.winfo_screenwidth()-pad, master.winfo_screenheight()-pad))
master.bind('<Escape>',self.toggle_geom)
def toggle_geom(self,event):
geom=self.master.winfo_geometry()
print(geom,self._geom)
self.master.geometry(self._geom)
self._geom=geom
root=tk.Tk()
app=FullScreenApp(root)
root.mainloop()
I think if you are looking for fullscreen only, no need to set geometry or maxsize etc.
You just need to do this:
-If you are working on ubuntu:
root=tk.Tk()
root.attributes('-zoomed', True)
-and if you are working on windows:
root.state('zoomed')
Now for toggling between fullscreen, for minimising it to taskbar you can use:
Root.iconify()
Here's a simple solution with lambdas:
root = Tk()
root.attributes("-fullscreen", True)
root.bind("<F11>", lambda event: root.attributes("-fullscreen",
not root.attributes("-fullscreen")))
root.bind("<Escape>", lambda event: root.attributes("-fullscreen", False))
root.mainloop()
This will make the screen exit fullscreen when escape is pressed, and toggle fullscreen when F11 is pressed.
This will create a completely fullscreen window on mac (with no visible menubar) without messing up keybindings
import tkinter as tk
root = tk.Tk()
root.overrideredirect(True)
root.overrideredirect(False)
root.attributes('-fullscreen',True)
root.mainloop()
Yeah mate i was trying to do the same in windows, and what helped me was a bit of lambdas with the root.state() method.
root = Tk()
root.bind('<Escape>', lambda event: root.state('normal'))
root.bind('<F11>', lambda event: root.state('zoomed'))
Just use:
# importing tkinter for gui
import tkinter as tk
# creating window
window = tk.Tk()
# setting attribute
window.state('zoomed')
window.title("Full window")
# creating text label to display on window screen
label = tk.Label(window, text="Hello world!")
label.pack()
window.mainloop()
If you want to hide everything except the window, you can also use:
import tkinter as tk
root = tk.Tk()
root.overrideredirect(True)
root.overrideredirect(False)
root.attributes('-fullscreen',True)
root.title("FullScreen")
label = tk.Label(root, text="Hello! Press 🪟 logo on the keypad > select the python logo > Close window to close")
labela = tk.Label(root, text="🎉🎉🎉")
label.pack()
labela.pack()
root.mainloop()
root = Tk()
root.geomentry('1599x1499')

Categories