python tkinter clicking on button to open new window - python

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

Related

Trying to write a tkinter popup with dynamic text and confirmation button

I am trying to make a popup for messages such as "Action completed" and I want a button on it to close the popup (A simple OK which quits only the popup). It also sometimes moves behind the window which is annoying. I have some code for the button but it has an issue with the geometry of the shape since the shape isn't exactly defined as it is variable through the size of font and text length.
import tkinter as tk
from tkinter import *
import pygame
import sys
def Text(Text_input, Font, Background, Foreground):
my_window = tk.Tk()
my_window.title(Text_input)
my_window.geometry()
help_label = tk.Label(my_window, font = Font, bg=Background, fg=Foreground, text = Text_input)
help_label.grid(row=0, column=0)
button = tk.Button(my_window, text="QUIT", fg="red", command=quit)
button.pack(side=tk.BOTTOM)
my_window.mainloop()
Text("Hello", "calibri 80", "white", "black")
From my own experience wanting to achieve this, I wrote a simple tkinter code export_success.py as follows:
from tkinter import *
from tkinter import ttk
import sqlite3
from tkinter.ttk import *
root = Tk()
root.geometry('280x100')
root.title("Export Status")
root.config(bg="")
style = ttk.Style()
label_0 = Label(root, text="Export Successful", width=20, background="white", foreground="grey15", font=("Arial, bold", 15)).place(x=50, y=23)
exit1 = Button(root, text='Exit', style='C.TButton', width=11, command=root.destroy).place(x=100, y=60)
root.mainloop()
I then just insert this code os.system('python export_success.py') at the end of my tkinker window that I'm working on.
In this case I'm exporting my information and wanted to know when it is successful.
I am not saying this is best practice and there might be other ways, I just found it to work out for me.

tkinter button stays clicked after using it to call other script

import tkinter as tk
from tkinter import filedialog, Text
from subprocess import call
import os
root = tk.Tk()
def buttonClick():
print('Button is clicked')
def openAgenda():
call("cd '/media/emilia/Linux/Programming/PycharmProjects/SmartschoolSelenium' && python3 SeleniumMain.py",
shell=True)
return
canvas = tk.Canvas(root, height=700, width=700, bg='#263D42')
canvas.pack()
frame = tk.Frame(root, bg='white')
frame.place(relwidth=0.8, relheight=0.8, relx=0.1, rely=0.1)
openFile = tk.Button(root, text='Open file', padx=10,
pady=5, fg="white", bg='#263D42', command=openAgenda)
openFile.pack()
root.mainloop()
the script it calls opens a new browser window, after finishing entering text in that window, it opens a new browser windows and loops.
meanwhile the tkinter button stays clicked, visually.
the reason your Tk GUI freezes is because you have everything running on 1 thread. The mainloop is haulted by the submit function call which must be taking a "long time", so you probably see "Not Responding" appear in your Tk window when you click the button. To fix this, you need spawn a separate thread for submit to run in, so that the mainloop can keep doing it's thing and keep your Tk window from freezing.
this is done using threading. Instead of your button directly calling submit, have the button call a function that starts a new thread which then starts submit. Then create another functions which checks on the status of the submit thread. You can add a status bar too
import tkinter as tk
from tkinter import filedialog, Text
from subprocess import call
import os
import threading
root = tk.Tk()
def buttonClick():
print('Button is clicked')
def openAgenda():
call("cd ' /media/emilia/Linux/Programming/PycharmProjects/SmartschoolSelenium' && python3 SeleniumMain.py",
shell=True)
canvas.update()
return
def start_Agenda_thread(event):
global Agenda_thread
Agenda_thread = threading.Thread(target=openAgenda)
Agenda_thread.daemon = True
Agenda_thread.start()
canvas = tk.Canvas(root, height=700, width=700, bg='#263D42')
canvas.pack()
frame = tk.Frame(root, bg='white')
frame.place(relwidth=0.8, relheight=0.8, relx=0.1, rely=0.1)
openFile = tk.Button(root, text='Open file', padx=10,
pady=5, fg="white", bg='#263D42', command=lambda:start_Agenda_thread(None))
openFile.pack()
root.mainloop()
Tkinter is single-threaded: it can only do one thing at a time. While the script is running, the GUI will be frozen. You'll need to do threading, multiprocessing, or find some other way to incorporate that other script in your GUI.

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.

How to code for a new window

how can I code for a new window? I have a button that creates a new one but I like to code for it and I don't know how. I think I must define the new window in any way but I don't know how to do this because for opening a new window with help of a button you must define the window self, but no name.
Thanks for helping!
I have create the button and its command in this way:
from Tkinter import *
import Tkinter as tk
master = tk.Tk()
def create_window(): #Definion und Festlegung neues Fenster
toplevel = Toplevel()
toplevel.title('result')
toplevel.geometry('1500x1000')
toplevel.focus_set()
Button(master, text='forward', command=create_window).pack(padx=5, anchor=N, pady=4)
master.mainloop()
Coding for the new window (or creating widgets in the new window) is similar to how you do it in the main window. Just pass the new window (toplevel) as the parent.
Here is an example that creates a Label and an Entry widgets in the new window.
from Tkinter import *
import Tkinter as tk
master = tk.Tk() # Create the main window
def create_window(): #Definion und Festlegung neues Fenster
toplevel = Toplevel()
toplevel.title('result')
toplevel.geometry('1500x1000')
# Create widges in the new window
label = tk.Label(toplevel, text="A Label", fg='blue')
entry = tk.Entry(toplevel)
label.pack()
entry.pack()
toplevel.focus_set()
Button(master, text='forward', command=create_window).pack(padx=5, anchor=N, pady=4)
master.mainloop()

Categories