Create Toplevel tkinter Window after the closure of previous Toplevel window - python

I have a list of n elements, I need to create a popup menu for each of them. Each popup would contain some checkboxes.
Condition: A new Toplevel popup window must open after the closure of the previous Toplevel window, and not all at the same time
My code:
from tkinter import *
#root gui
root = Tk()
root.title("test")
root.geometry("300x400")
# Need three popup windows
a = ["one", "two", "three"]
b = []
def open():
for _ in range(len(a)):
top = Toplevel()
top.title("selections")
def next_window():
top.destroy()
show() # This function is supposed to show the selections of each popup window on root gui
for i in range(3):
b.append(IntVar())
b[i].set(0) # de selecting all checkboxes intiially
# checkboxes
Checkbutton(top, text=a[i], variable=b[i]).pack()
Button(top, text = "Submit", command=next_window).pack()
Button(top, text = "skip", command=top.destroy).pack() # this button is used to skip the popup if no selection required
def show():
# printing selections made on each popup window
for i in range(3):
Label(root, text=b[i].get()).pack()
mB = Button(root, text="print selections", command=open).pack()
root.mainloop()
My concern: All three popups are opening at the same time for me now.

You need to call top.wait_window() at the end inside the for loop:
for _ in range(len(a)):
top = Toplevel(root)
top.title("selections")
def next_window():
top.destroy()
show() # This function is supposed to show the selections of each popup window on root gui
for i in range(3):
b.append(IntVar())
b[i].set(0) # de selecting all checkboxes intiially
# checkboxes
Checkbutton(top, text=a[i], variable=b[i]).pack()
Button(top, text = "Submit", command=next_window).pack()
Button(top, text = "skip", command=top.destroy).pack() # this button is used to skip the popup if no selection required
top.grab_set() # route all events to this window
top.wait_window() # wait for current window to close

Related

Button not showing up while opening new page (python tkinter)

I want to use the listbox in tkinter in order to open a new window with a button, but when I'm pressing a message it only opens the window, without the button.
from tkinter import *
from playsound import playsound
import os
# create a window as root using Tk() function
root = Tk()
root.geometry("200x200")
# create a changecolor function
# to change background color of window
def new_win():
top2 = Toplevel(root)
top2.geometry('200x200')
top2.title("display Window")
# photo2 = PhotoImage(file=r"hearing.png")
button = Button(text='wtf')
def changecolor(event):
# get selected list box color item
new_win()
# create listbox
listbox = Listbox(root , font=('times 20 bold'), height=5,width=10)
# insert color items into listbox
listbox.insert(1, 'first')
listbox.insert(2, 'second')
listbox.insert(3, 'third')
listbox.insert(4, 'forth')
listbox.pack(pady=20)
# bind the click event with listbox and
# call changecolor() function
listbox.bind('<<ListboxSelect>>', changecolor)
root.mainloop()
Any suggestion would be very helpful.
You can change the line 16
button = Button(text='wtf')
to
button = Button(top2,text='wtf')
button.pack()

how can I create a cancel button in tkinter

Hi I'm new in tkinter and I was trying to code a window with a button creating a new window. I want to add a new button (for cancel) in new window. I cant add a cancel button in my second window.
here is my code:
from tkinter import *
from tkinter.ttk import *
master = Tk()
master.geometry("200x200")
def openNewWindow():
newWindow = Toplevel(master)
newWindow.title("New Window")
newWindow.geometry("200x200")
Label(newWindow,
text="This is a new window").pack()
label = Label(master,
text="This is the main window")
label.pack(pady=10)
btn = Button(master,
text="Click to open a new window",
command=openNewWindow)
btn.pack(pady=10)
mainloop()
Insert the following code lines at the end of openNewWindow function to destroy newWindow.
clo = Button(
newWindow, text = "Close new window", command = newWindow.destroy)
clo.pack(pady = 10)
If you need to perform some action before destroying newWindow then create a function.
def closer():
# do something
newWindow.destroy()
And change openNewWindow close button like this.
clo = Button(
newWindow, text = "Close new window", command = closer)
clo.pack(pady = 10)

How can I store data on Toplevel?

On the toplevel window, if the toplevel is closed after get some input from the user using the entry widget, and then the same toplevel is opened by pressing the same button, is there a way to see the entry we received from the user in the entry widget?
For example user enter his name on toplevel window, and close the toplevel.Then the user open same toplevel,i want it to see his name in the entry widget.
Try this:
import tkinter as tk
last_user_input_entry = ""
last_user_input_button = 0
def on_closing():
global entry, top, last_user_input_entry, last_user_input_button, button_var
text = entry.get()
last_user_input_entry = text
last_user_input_button = button_var.get()
print("The text entered =", last_user_input_entry)
print("Checkbutton state =", last_user_input_button)
top.destroy()
def start_top():
global entry, top, button_var
top = tk.Toplevel(root)
top.protocol("WM_DELETE_WINDOW", on_closing)
entry = tk.Entry(top)
entry.pack()
entry.insert("end", last_user_input_entry)
button_var = tk.IntVar()
button_var.set(last_user_input_button)
button = tk.Checkbutton(top, variable=button_var)
button.pack()
root = tk.Tk()
button = tk.Button(root, text="Open toplevel", command=start_top)
button.pack()
root.mainloop()
Basically we intercept the window closing and handle that our self. We also have a variable that stored the last user input and we put it in the tkinter.Entry after we create it.

How to create a simpledialog-like window with a combo with tkinter?

simpledialog or filedialog are widgets very convenient to use.
I would like to do the same :
modal window which pops up on screen like these simpledialogs
combo box inside
and when I select a value in combo, return this value without needing a button
Something like:
def askComboValue():
root = Tk() #how to pops up this window?
label = ttk.Label(root, text = "select your value")
label.pack()
box_value = ''
combo = ttk.Combobox(root, textvariable=box_value, values=['bla', 'bli', 'blo'])
combo.current(0)
combo.pack()
combo.bind("<<ComboboxSelected>>", returnValue) #how to catch this value?
root.grab_set_global() #is it the right way to make it modal?
root.mainloop()
return box_value #how to return this value?
Does anyone know how to deal with it?
Thanks for your help
If the function is called when there is already a tkinter window, then better use Toplevel() instead of Tk(). Also box_value should be instance of StringVar() instead. grab_set() is used instead of grab_set_global() as well.
Below is an example based on your code:
import tkinter as tk
from tkinter import ttk
def askComboValue(*values):
top = tk.Toplevel() # use Toplevel() instead of Tk()
tk.Label(top, text='Select your value').pack()
box_value = tk.StringVar()
combo = ttk.Combobox(top, textvariable=box_value, values=values)
combo.pack()
combo.bind('<<ComboboxSelected>>', lambda _: top.destroy())
top.grab_set()
top.wait_window(top) # wait for itself destroyed, so like a modal dialog
return box_value.get()
def test():
result = askComboValue('bla', 'bli', 'blo')
print(result)
root = tk.Tk()
tk.Button(root, text='Test', command=test).pack()
root.mainloop()

Tkinter remove/overwrite elements from Frame

I created a button that retrieves a list from a DataFrame based on some input from a text field. Everytime the button is pressed, the list will be refreshed. I output the list (as an OptionMenu) in a separate Frame (outputFrame). However, every time I press this button, a new OptionMenu is added to the Frame (instead of overwriting the previous one). How can I make sure that the content of 'ouputFrame' is overwritten each time I press the button?
# start
root = Tkinter.Tk()
# frames
searchBoxClientFrame = Tkinter.Frame(root).pack()
searchButtonFrame = Tkinter.Frame(root).pack()
outputFrame = Tkinter.Frame(root).pack()
# text field
searchBoxClient = Tkinter.Text(searchBoxClientFrame, height=1, width=30).pack()
# function when button is pressed
def getOutput():
outputFrame.pack_forget()
outputFrame.pack()
clientSearch = str(searchBoxClient.get(1.0, Tkinter.END))[:-1]
# retrieve list of clients based on search query
clientsFound = [s for s in df.groupby('clients').count().index.values if clientSearch.lower() in s.lower()]
clientSelected = applicationui.Tkinter.StringVar(root)
if len(clientsFound) > 0:
clientSelected.set(clientsFound[0])
Tkinter.OptionMenu(outputFrame, clientSelected, *clientsFound).pack()
else:
Tkinter.Label(outputFrame, text='Client not found!').pack()
Tkinter.Button(searchButtonFrame, text='Search', command=getOutput).pack()
root.mainloop()
We can actually update the value of the OptionMenu itself rather than destroying it (or it's parent) and then redrawing it. Credit to this answer for the below snippet:
import tkinter as tk
root = tk.Tk()
var = tk.StringVar(root)
choice = [1, 2, 3]
var.set(choice[0])
option = tk.OptionMenu(root, var, *choice)
option.pack()
def command():
option['menu'].delete(0, 'end')
for i in range(len(choice)):
choice[i] += 1
option['menu'].add_command(label=choice[i], command=tk._setit(var, choice[i]))
var.set(choice[0])
button = tk.Button(root, text="Ok", command=command)
button.pack()
root.mainloop()

Categories

Resources