"Resetting" a tkinter window - python

I'm currently trying to create a command centre to integrate with one of my other python programs, however, I am quite new to Tkinter, and as such, I was wondering if there was a way to "reset" a window that has widgets in it so that I can have a clean window to place new widgets in, without storing any data or using system resources. Here is the code I currently have:
import tkinter
tk = tkinter
window = tk.Tk()
def login():
window.title("SCC: Login")
header = tk.Label(window, text = "Please Login").pack()
frame = tkinter.Label(window, text = "Username").pack()
frame = tkinter.Entry(window).pack()
frame = tkinter.Label(window, text = "Password").pack()
frame = tkinter.Entry(window).pack()
frame = tkinter.Checkbutton(window, text = "Keep Me Logged In").pack()
frame = tkinter.Button(window, text = "Login", command = mainMenu).pack()
window.mainloop()
def mainMenu():
()
window.title("SCC")
tk.Label(window, text = "Welcome to the Sentinel Command Center").pack()
tk.Button(window, text = "Network Utilities", fg = "orange").pack()
tk.Button(window, text = "Image Recognition", fg = "orange").pack()
tk.Button(window, text = "Voice Recognition", fg = "orange").pack()
window.mainloop()
login()
also as a side note i am fully aware the current password form is non functional, its just a placeholder for now until i find a better method of authorization for the code.

Arguably, the easiest way to reset it is to put all of your widgets inside a frame, and then create a function that creates the frame. Then, to do a reset you can destroy the current frame and call your function to recreate it.

Update:
I found a functional if a convoluted method to doing this, just by creating separate windows, then withdrawing the login window once the main menu has been called. Here is the code if you want to use it:
mainWindow = tk.Tk()
loginWindow = tk.Tk()
version = ("v0.1")
def centerwindowLogin(width=300, height=200):
screen_width = loginWindow.winfo_screenwidth()
screen_height = loginWindow.winfo_screenheight()
x = (screen_width/2) - (width/2)
y = (screen_height/2) - (height/2)
loginWindow.geometry('%dx%d+%d+%d' % (width, height, x, y))
def centerwindowMain(width=300, height=200):
screen_width = mainWindow.winfo_screenwidth()
screen_height = mainWindow.winfo_screenheight()
x = (screen_width/2) - (width/2)
y = (screen_height/2) - (height/2)
mainWindow.geometry('%dx%d+%d+%d' % (width, height, x, y))
def login():
loginWindow.title("SCC v0.1")
header = tk.Label(loginWindow, text = "Please Login").pack()
tk.Label(loginWindow, text = "Username").pack()
tk.Entry(loginWindow).pack()
tk.Label(loginWindow, text = "Password").pack()
tk.Entry(loginWindow).pack()
tk.Checkbutton(loginWindow, text = "Keep Me Logged In").pack()
tk.Button(loginWindow, text = "Login", command = mainMenu).pack()
centerwindowLogin(300, 175)
loginWindow.mainloop()
def mainMenu():
loginWindow.withdraw()
mainWindow.title("SCC v0.1")
tk.Label(mainWindow, text = "Welcome to the Sentinel Command Center").pack()
tk.Button(mainWindow, text = "Network Utilities", fg = "orange").pack()
tk.Button(mainWindow, text = "Image Recognition", fg = "orange").pack()
tk.Button(mainWindow, text = "Voice Recognition", fg = "orange").pack()
centerwindowMain(500, 400)
mainWindow.mainloop()
login()

This function can be used to remove all existing widgets:
def wempty(w):
for w in w.winfo_children():
w.destroy()

Related

Variable not defined / function not defined

I am trying to code a CPS test for fun but I ran into a problem:
I defined a function at the beginning of the code and than I defined a tkinter button which has this function as command and the button should disappear in this function. When I do it like this it says that the variable of the button isn't defined yet but when I defined it vice versa so first the button and then the function it says that the function is not defined yet.
Can anyone help me?
(Sorry for my bad English)
import tkinter as tk
root = tk.Tk()
root.title("CPS test")
root.geometry("1000x1000")
root.configure(bg='white')
def getstring():
duration = entry.get()
entry.delete(0)
entry.place_forget()
okbutton.place_forget
lab1 = tk.Label(text = "How long should the CPS test last? 2,5 or 10 seconds?(Answer with 2,5,10)", font = "Ariel 20", bg = "#FFFFFF")
button = tk.Button(root, text = "Click me!", font = "Ariel 50", bg = "#FFFFFF", fg = "#000000")
entry = tk.Entry(root, font=('Arieal 20'), bd = 2)
okbutton = tk.Button(root, text = "OK", font = "Ariel 20", bg = "#FFFFFF", fg = "#000000", bd = 2, command = getstring())
lab1.place(x = 45,y = 250)
entry.place(x = 344, y = 350)
entry.insert(0, "Enter your answer here!")
okbutton.place(x = 465, y = 400)
root.mainloop()
I think the error is on the button name.
def getstring():
duration = entry.get()
entry.delete(0)
entry.place_forget()
button.place_forget
Just replace "okbutton" by "button" and it should work.
Else just declared the "okbutton" before the function

Update text widget in tkinter from function

The problem:
I am trying to update the same text widget box from a function that contains some text. Instead a whole new text window appears every time.
Here is my code:
from tkinter import *
import os
#Tkinter graphics
homepage = Tk()
homepage.title("My first GUI")
# set size of window
homepage.geometry('1200x400')
# Add image file
bg = PhotoImage(file = "maxresdefault.png")
# Show image using label
label1 = Label( homepage, image = bg)
label1.place(x = 0, y = 0)
label2 = Label( homepage, text = "Test App")
label2.pack()
# Create Frame
frame1 = Frame(homepage)
frame1.pack()
#button initatiors
def buttonupdate():
S = Scrollbar(homepage)
T = Text(homepage, height=100, width=30)
T.pack()
T.pack(side=RIGHT, fill= Y)
S.pack(side = RIGHT, fill = Y)
S.config(command=T.yview)
T.insert(END, "test")
T.config(yscrollcommand=S.set, state=DISABLED)
# Static buttons
tickets30button = Button(text = "This is button 1", command=buttonupdate)
tickets30button.place(x=0, y=26)
mcibutton = Button(text = "This is button 2")
mcibutton.place(x=0, y=52)
hdebutton = Button(text = "This is button 3")
hdebutton.place(x=0, y=78)
homepage.mainloop()
Here is the result if I click on the first button three times:
Let me know if you have any suggestions that I can try.
Thank you for your time,
I was able to update my text window instead of create a new one, upon each click of a button, thanks to #TheLizzard.
He mentioned to move the section of code that creates the text window outside of the function and keep the section of code that creates the text, inside the function.
Before:
#button initiators
def buttonupdate():
S = Scrollbar(homepage)
T = Text(homepage, height=100, width=30)
T.pack()
T.pack(side=RIGHT, fill= Y)
S.pack(side = RIGHT, fill = Y)
S.config(command=T.yview)
T.insert(END, "test")
T.config(yscrollcommand=S.set, state=DISABLED)
After: (UPDATED)
S = Scrollbar(homepage)
T = Text(homepage, height=100, width=30)
T.pack(side=RIGHT, fill= Y)
S.pack(side = RIGHT, fill = Y)
S.config(command=T.yview)
T.config(yscrollcommand=S.set, state=DISABLED)
#button initatiors
def myTicketstatusbutton():
T.delete(1.0,END)
T.insert(END, "test")

How to save a data after closing a window?

I'm trying to make some GUI on Python3 with tkinter. So far I have Main Window and 'Test' button on it, which opens second window. Second window has entry, label, save and close buttons. When you type something in entry and press save button, label shows the text you typed in entry. But after closing this window and opening it again, label shows nothing. How do I make this label to show the text that were typed last time before closing? For example, I type 'Hi' in entry, press 'Save', then I press 'Close', then I open this window again and label shows 'Hi'
import tkinter as tk
def save_data(entry, t):
t.config(text = entry.get())
def close_action(current_window):
current_window.destroy()
def insertMainInfo():
new_window = tk.Tk()
new_window.geometry("307x131")
new_window.title("TestWindow")
test_entry = tk.Entry(new_window)
test_entry.place(relx = 0.283, rely = 0.1, height = 24, width = 127)
text = tk.Label(new_window)
text.place(relx = 0.283, rely = 0.25, height = 24, width = 127)
save_button = tk.Button(new_window, command = lambda: save_data(test_entry, text))
save_button.place(relx=0.283, rely=0.45, height=24, width=127)
save_button.configure(text = "Save")
close = tk.Button(new_window, command = lambda: close_action(new_window))
close.place(relx=0.283, rely=0.687, height=24, width=127)
close.configure(text = "Close")
new_window.mainloop()
if __name__ == '__main__':
top = tk.Tk()
top.geometry("307x131+557+330")
top.resizable(width=False, height=False)
top.title("MainWindow")
new_window_button = tk.Button(top, command = insertMainInfo)
new_window_button.place(relx=0.283, rely=0.687, height=24, width=127)
new_window_button.configure(text = "Test")
main_label = tk.Label(top)
main_label.place(relx=0.033, rely=0.153, height=41, width=284)
main_label.configure(text = "TestLabel")
top.mainloop()
I have to confess that your question heading is a bit ambiguity.
If you just want to update a label of last entry, here a simple way of modifying your code.
As advised, as a good practice we only have one Tk() in a program, other new windows or pop-up windows should use Toplevel() of tkinter class; So I use this in your insertMainInfo() function.
The point here is to define a variable, I called last_entry and initially is empty or ‘’. Use this as parameter in new_window button in main program (after if __name__ == '__main__': ) to this variable (I also add lambda function here).
Then we define it as global in save_data function, so as it can be known later by other functions or main program as the last entry before new_window is closed.
Here I modify your code as said above, and I have tested it, and it works as expected.
import tkinter as tk
def save_data(entry, t):
global last_entry
last_entry = entry.get()
t.config(text = last_entry)
def close_action(current_window):
current_window.destroy()
def insertMainInfo(last_entry):
new_window = tk.Toplevel()
new_window.geometry("307x131")
new_window.title("TestWindow")
test_entry = tk.Entry(new_window)
test_entry.place(relx = 0.283, rely = 0.1, height = 24, width = 127)
text = tk.Label(new_window, text=last_entry)
text.place(relx = 0.283, rely = 0.25, height = 24, width = 127)
save_button = tk.Button(new_window, command = lambda: save_data(test_entry, text))
save_button.place(relx=0.283, rely=0.45, height=24, width=127)
save_button.configure(text = "Save")
close = tk.Button(new_window, command = lambda: close_action(new_window))
close.place(relx=0.283, rely=0.687, height=24, width=127)
close.configure(text = "Close")
new_window.mainloop()
# --- A Simple Data Structure ---
last_entry = ''
if __name__ == '__main__':
top = tk.Tk()
top.geometry("307x131+557+330")
top.resizable(width=False, height=False)
top.title("MainWindow")
new_window_button = tk.Button(top, command = lambda: insertMainInfo(last_entry))
new_window_button.place(relx=0.283, rely=0.687, height=24, width=127)
new_window_button.configure(text = "Test")
main_label = tk.Label(top)
main_label.place(relx=0.033, rely=0.153, height=41, width=284)
main_label.configure(text = "TestLabel")
top.mainloop()

Refresh my tkinter label and lets it overwrite it with different output content

I have a Submit button that prints the output on the tkinter widget label. Everytime I change the input and click the Submit the output is displayed but not at the same place i.e. The previous content of the label is not overwritten.
from tkinter import *
from tkinter import filedialog
root = Tk()
root.title("ImageValidation ")
root.geometry("600x600+100+100")
pathlist = [None, None] # holds the two files selected
labels = []
def browse_button(index):
global filename
filename = filedialog.askopenfilename(title = "Choose your file",filetypes = (("jpeg files","*.jpeg"),("all files","*.*")))
pathlist[index] = filename
heading = Label(root, text = "Select 2 images you want to Validate",
font=("arial",15,"bold","underline"), fg="blue").pack()
label1 = Label(root, text = "Enter Image 1", font=("arial",10,"bold"),
fg="black").place(x=10, y = 100)
label2 = Label(root, text = "Enter Image 2", font=("arial",10,"bold"),
fg="black").place(x=10, y = 200)
button = Button(root,text="Choose an Sign1",width = 30,command= lambda:
browse_button(0)).place(x=250, y= 100)
button = Button(root,text="Choose an Sign2",width = 30,command=
lambda: browse_button(1)).place(x=250, y= 200)
def display():
ImageVerification(pathlist[0], pathlist[1])
l1 = Label(root,text=Scriptoutput, width = 200 )
l1.pack(side='bottom', padx=50, pady=50)
#Scriptoutput is the output variable from the main code.
submit_button = Button(text="Submit", width=15,command = display)
submit_button.pack(side='bottom', padx=15, pady=15)
root.mainloop()
A 'refresh' button that would clear the Label of its content and lets you overwrite it.
I am taking your function ImageVerification() as a blackbox and assuming it is working.
The reason this is happening is because you create a new Label, whenever the Submit button is pressed. What you have to do is to create the display Label outside the function and configure its text, whenever the button is pressed. Something like this.
l1 = Label(root, text="", width=200)
l1.pack(side='bottom', padx=50, pady=50)
def display():
ImageVerification(pathlist[0], pathlist[1])
l1.configure(text=Scriptoutput)
#Scriptoutput is the output variable from the main code.
submit_button = Button(text="Submit", width=15,command = display)
submit_button.pack(side='bottom', padx=15, pady=15)

tkinter overrideredirect stops entry working

I would like to create a "Borderless" window in python and my code works without overrideredirect, however when I use this the input is disallowed. I can not click into the Entry box
*This is the code which needs to be figured out, it is currently in a function and there is another 500 lines of code to go with it :D *
newWindow = tkinter.Tk()
w = 300
h = 400
ws = 1024
hs = 768
x = (ws/2) - (w/2)
y = (hs/2) - (h/2)
newWindow.configure(background="#2E393D")
newWindow.overrideredirect(True)
frame = tkinter.Frame(newWindow)
name = tkinter.Label(newWindow, background="#1c1c1c", width=2, height=4)
name.pack()
global outputl
global inputl
inputl = tkinter.StringVar()
outputl = tkinter.StringVar()
def nomic(empty):
reply = inputl.get()
inputl.set("")
mainProcess(reply)
if way == "a":
import speech_recognition as sr
r = sr.Recognizer()
with sr.Microphone() as source:
audio = r.listen(source)
try:
reply = r.recognize_google(audio)
mainProcess(reply)
except sr.UnknownValueError:
backCreateFile("I did not understand that !")
else:
inputBox = tkinter.Entry(frame, textvariable=inputl, width=40,foreground="#2E393D", background="white", font=("Ubuntu", 13))
inputBox.bind("<Return>", nomic)
inputBox.pack(fill="x")
outputLabel = tkinter.Label(newWindow, textvariable=outputl)
outputLabel.config( background="#2E393D", foreground="white", wraplength=280, pady=10, font=("Ubuntu", 13))
outputLabel.pack(fill="x")
weatherV = tkinter.StringVar()
weatherV.set("Current Weather - " + status)
weatherLabel = tkinter.Label(newWindow, justify="left", textvariable=weatherV, background="#2E393D", foreground="white", font=("Ubuntu", 13), pady=7).pack(fill="x")
tempV = tkinter.StringVar()
tempV.set("Current Temperature - " + str(ctemp))
tempLabel = tkinter.Label(newWindow, justify="left", textvariable=tempV, background="#2E393D", foreground="white", font=("Ubuntu", 13), pady=7).pack(fill="x")
frame.pack()
I had a similar issue and was able to get around it by using
root.attributes('-fullscreen', True)
This makes the GUI fill the screen completely, creating a 'borderless' window, but still allows for interaction with the entry widgets and setting focus.
I created an account just so i could answer this.
delete the line with your overridedirect statement and replace it with:
root.wm_attributes('-type', 'splash');
^ You are welcome.
Here is minimal code that works on Windows with Python 3.6 and tk 8.6. The popup is in its default position, the upper left corner the screen.
import tkinter as tk
root = tk.Tk()
tag = tk.Label(root, text='Popup entry contents: ')
var = tk.StringVar(root, 'var')
label = tk.Label(root, textvariable=var)
tag.pack(side='left')
label.pack(side='left')
pop = tk.Toplevel(root)
pop.overrideredirect(True)
entry = tk.Entry(pop, textvariable=var)
entry.pack()
#pop.lift() # Needed? for tk 8.5.18+, not for 8.6
Test this on your system, and if it works, figure out what you did differently in your code.

Categories