How To Put Widgets In A New Tkinter Window? - python

I wanted to add widgets to a new tkinter window, so I tried this:
old_window = Tk()
new_window = Tk()
old_window.destroy()
new_window.geometry("750x550")
image = Label(new_window, image = dernier).pack
button1 = Button(new_window, text = "Oui", font= ("", 25), command = button1_press).place(x=250, y=475)
button2 = Button(new_window, text = "Non", font= ("", 25), command = button2_press).place(x=425, y=475)
But, just a basic window pops out, with nothing inside.
Python version: 3.9.7
Integrated Development Environnement (Also known as IDE): Visual Studio Code.

The tk.Tk() class isn't just a window, it's also what controls the entire application and has an associated Tcl interpreter. Creating multiple of these, and destroying them part way through an application, can cause many problems. Instead, for creating a new window, use the tk.Toplevel() class.
For example:
import tkinter as tk
root = tk.Tk()
a = tk.Toplevel()
b1 = tk.Button(a, text="new toplevel", command=lambda: tk.Toplevel())
root.mainloop()

Related

Tkinter Toplevel inf different file/function

I am trying to create a Toplevel window, however, this Toplevel is called from a different file in the same directory within a function.
Apologies I am by no means a tkinter or python guru. Here are the two parts of the code. (snippets)
#File 1 (Main)
import tkinter as tk
from tkinter import *
import comm1
from comm1 import com1
root = tk.Tk()
root.title("")
root.geometry("1900x1314")
#grid Center && 3x6 configuration for correct gui layout
root.grid_rowconfigure(0, weight=1)
root.grid_rowconfigure(11, weight=1)
root.grid_columnconfigure(0, weight=1)
root.grid_columnconfigure(11, weight=1)
#background image
canvas = Canvas(root, width=1900, height=1314)
canvas.place(x=0, y=0, relwidth=1, relheight=1)
bckground = PhotoImage(file='img.png')
canvas.create_image(20 ,20 ,anchor=NW, image=bckground)
#command to create new Toplevel
btn1 = tk.Button(root, text='Top', command=com1, justify='center', font=("Arial", 10))
btn1.config(anchor=CENTER)
btn1.grid(row=4, column=1)
#File 2 (Toplevel)
#command for new window
def com1():
newWindow1 = Toplevel(root)
newWindow1.title("")
newWindow1.geometry("500x500")
entry1 = tk.Entry(root, justify='center' , font=("Arial", 12), fg="Grey")
newWindow1.pack()
newWindow1.mainloop()
The weird part is this worked perfectly for a few minutes and without changing any code it just stopped working.
Where am I going wrong?
You need to pass root as an argument to com1
Also, you only need to start mainloop once, and that should probably be in the main file. You do not need to call it each time you create a new window.
Thanks everyone that answered,
Decided to bypass the problem with better structuring in a single file. :)

python tkinter restore window without title bar

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

How do I make a button that closes one tkinter window and opens another?

When I make a button that closes the current window and opens another, the current window doesn't close.
from tkinter import *
root = Tk()
def new_window():
root.quit()
new_window = Tk()
new_window.mainloop()
Button(root, text="Create new window", command=new_window).pack()
root.mainloop()
(This isn't my program, it's just an example)
You should be able to do it like this:
import tkinter as tk
root = tk.Tk()
def new_window():
root = tk.Tk()
test = tk.Button(root, text="Create new window", command= lambda:[root.destroy(), new_window()]).pack()
root.mainloop()
test = tk.Button(root, text="Create new window", command= lambda:[root.destroy(), new_window()]).pack()
root.mainloop()
This will literally keep opening the exact same window with a button. The lambda allows you to call multiple functions. By calling .destroy() on your root window, it destroys your window, but doesn’t stop the program. Then you create a new root window with your function.
You can use this technique on your actual script.

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

Python + Tkinter: How to open two independent windows from two subfunctions?

I want to have the two windows from the two subfunctions opened together, when the programm is run.
(Well, to be more exactly, the two subfunctions dont run together. But as a result, I want to have two windows shown.)
But my following code only allows me to open one window at the same time.
I would prefer to have the two-subfunctions-structure. So how can I change the code? Thanks for your help!
from Tkinter import *
def Window1():
root1 = Tk()
root1.title("Window 1")
Label1 = Label(root1,text="abc",width=60)
Label1.grid(row=0, column=0)
root1.mainloop()
def Window2():
root2 = Tk()
root2.title("Window 2")
Label2 = Label(root2,text="ABC" ,width=60)
Label2.grid(row=0, column=0)
root2.mainloop()
Window1()
Window2()
If you are opening more than one windows, you should make any windows after the first an instance of a Toplevel widget.
The below example shows how this could be done. The first windows is the main one and will kill the app if its closed. The second windows will not kill the app but will just close itself.
from Tkinter import *
def mainwindow(root):
root.title("Window 1")
Label1 = Label(root,text="abc",width=60)
Label1.grid(row=0, column=0)
def otherwindow(parent):
root2 = Toplevel(parent)
root2.title("Window 2")
Label2 = Label(root2,text="ABC" ,width=60)
Label2.grid(row=0, column=0)
root = Tk()
mainwindow(root)
otherwindow(root)
root.mainloop()

Categories