Python Tkinter time.sleep() - python

I am making a program and i have a problem. When using time.sleep() like it shows in the code, i would like it to wait 5 secs after the first label appears and then show the second one, but instead when i press the 'start' button it waits 5 secs and then displays both labels at once. (The code i am interested in is just at the end, in guess_number)
Here's the code:
from tkinter import *
from tkinter import font
from datetime import datetime
import time
class Window(Frame):
def __init__(self, master):
Frame.__init__(self, master)
self.master = master
self.master.resizable(0,0)
master.title("Arcade Games")
master.geometry("800x600+560+240")
now = datetime.now()
hour = now.hour
minutes = now.minute
b = Button(self, text="Guess the number", command=self.new_window, cursor='hand2', relief='groove')
b.pack()
self.customFont = font.Font(master, font="Heraldica", size=12)
labelTime = Label(self.master, text=str(hour)+" : "+str(minutes), font=self.customFont)
labelTime.pack(side='bottom')
def new_window(self):
id = "Welcome to the 'Guess your number' game!\nAll you need to do is follow the steps\nand I will guess your number!\n\nClick the button to start!!"
self.window = Toplevel(self.master)
self.window.resizable(0,0)
self.label = Label(self.window, text=id, font=self.customFont)
self.label.pack(side="top", fill="both", padx=20, pady=20)
self.button = Button(self.window, text="Start", relief='groove')
self.button.config(width=20, height=2)
self.button.bind("<Button-1>", self.guess_number)
self.button.pack()
self.window.title("Guess the number")
self.window.geometry("400x300+710+390")
def guess_number(self, event):
self.button.destroy()
self.label.destroy()
labelGuess = Label(self.window, text="Pick any number.\nIt can be 3, 500 or even 1,324,324", font=self.customFont)
labelGuess.pack(padx=20, pady=20)
time.sleep(5)
labelGuess1 = Label(self.window, text="Now double it", font=self.customFont)
labelGuess1.pack(padx=20, pady=20)
if __name__ == "__main__":
root = Tk()
view = Window(root)
view.pack(side="top", fill="both")
root.mainloop()
Any help is appreciated!

Rather than use time.sleep() to stop the main task, try scheduling an event with tkinter's after(), like so:
def guess_number(self, event):
self.button.destroy()
self.label.destroy()
labelGuess = Label(self.window, text="Pick any number.\nIt can be 3, 500 or even 1,324,324", font=self.customFont)
labelGuess.pack(padx=20, pady=20)
self.window.after(5000, self.make_guess1_visible)
def make_guess1_visible(self):
labelGuess1 = Label(self.window, text="Now double it", font=self.customFont)
labelGuess1.pack(padx=20, pady=20)

Related

Tkinter Button does nothing when clicked

This is the code for my personal project, for some reason, I can't get the button to do anything when pressed.
Edit: So I managed to fix the text deleting after each input, so now it will continue to output as many passwords as I want. I removed the 0.0 in output.delete so it doesn't default the text to 0 after each generated password.
from tkinter import *
from datetime import datetime
import pyperclip as pc
def close_window():
window.destroy()
exit()
# Main GUI program
window = Tk()
window.frame()
window.grid_rowconfigure((0, 1), weight=1)
window.grid_columnconfigure((0, 1), weight=1)
window.title("PW Gen")
window.geometry('+10+10')
window.configure(background="black")
Label(window, bg="black", height=0, width=25, font="Raleway").grid(row=1, column=0, sticky=NSEW)
# Enter the last 4 and generate the password
Label(window, text="Enter the last 4 digits of the Reader Name:", bg="black", fg="white", font="Raleway 12 bold").grid(row=1, column=0, sticky=W)
textentry = Entry(window, width=53, bg="white")
textentry.grid(row=2, column=0, sticky=W)
Button(window, text="Generate Password", width=16, font="Raleway 8 bold", command=click).grid(row=3, column=0, sticky=W)
# Output the password
Label(window, text="\nPassword", bg="black", fg="white", font="Raleway 12 bold").grid(row=4, column=0, sticky=W)
output = Text(window, width=40, height=4, wrap=WORD, background="white")
output.grid(row=5, column=0, columnspan=2, sticky=W)
# Button and Text To Quit GUI
Label(window, text="Click to Quit", bg="black", fg="white", font="Raleway 12 bold").grid(row=6, column=0, sticky=W)
Button(window, text="Quit", width=14, font="Raleway 8 bold", command=close_window).grid(row=7, column=0, sticky=W)
window.mainloop()
Not exactly the best solution but you can definitely give it a try.
import tkinter as tk
from datetime import datetime
import string
import pyperclip as pc
import random
root = tk.Tk()
root.title("PW Gen")
root.geometry('+10+10')
mainframe = tk.Frame(root)
text = tk.Text(root, height=5, width=25, font="Raleway")
def pwgen():
last4=text.get('1.0','end')[-5:]
j=[char for char in last4 if char in string.ascii_uppercase or char in string.ascii_lowercase]
print(j)
random.shuffle(j)
print(j)
today = datetime.today()
pw = int(today.strftime("%d")) * int(today.strftime("%m"))
last4=''.join(j)
pwgen = "$ynEL" + str(pw) + str()
pc.copy(pwgen)
print("\nThe password is $ynEL" + str(pw) + str(last4))
class Application(tk.Frame):
def __init__(self, master=None):
super().__init__(master)
self.quit1 = tk.Button(self, text="QUIT", fg="black", command=self.master.destroy)
self.quit1.pack(side="top")
text.pack(side="bottom")
self.b2 = tk.Button(self)
self.create_widgets()
self.pack()
def create_widgets(self):
self.b2["text"] = "GenPW"
self.b2["command"] = pwgen
self.b2.pack(side="left")
def b1(self):
self.b2 = tk.Button(self, text="Generate PW", command=pwgen)
app = Application(root)
root.mainloop()
The code has many problems.
mainframe is not shown and never used.
Text is shown, but never used.
Text is packed inside Application but is not part of Application.
pwgen uses input and no GUI widget. A infinte loop with a GUI application is not good.
You should use the attributes of a datetime directly.
You should not generate the password at two places in the code.
You should not name a local variable like the function.
In Application you are using b1 as method, this method is overloaded by the attribute b1, so you cannot use the method anymore.
In the method b1 you are generating a new butten instead of calling the function pwgen.
import tkinter as tk
from datetime import datetime
import pyperclip as pc
def pwgen():
today = datetime.today()
pw = today.day * today.month
last4 = input("Last 4 of Reader Name [****] ")
password = f"$ynEL{pw}{last4}"
pc.copy(password)
print("\nThe password is", password)
class Application(tk.Frame):
def __init__(self, master=None):
super().__init__(master)
self.quit = tk.Button(self, text="QUIT", fg="black", command=self.master.destroy)
self.quit.pack(side="top")
self.b1 = tk.Button(self, text="GenPW", command=self.click_b1)
self.b1.pack(side="left")
def click_b1(self):
pwgen()
def main():
root = tk.Tk()
root.title("PW Gen")
root.geometry('+10+10')
text = tk.Text(root, height=5, width=25, font="Raleway")
text.pack(side="bottom")
app = Application(master=root)
app.pack()
root.mainloop()
if __name__ == "__main__":
main()
This works. I have used grid manager for more control and removed unused code.
import tkinter as tk
from tkinter import *
from datetime import datetime
import pyperclip as pc
root = tk.Tk()
root.title("PW Gen")
root.geometry('+10+10')
Text = tk.Text(root, height=5, width=25, font="Raleway")
def pwgen():
while True:
today = datetime.today()
pw = int(today.strftime("%d")) * int(today.strftime("%m"))
last4 = input("Last 4 of Reader Name [****] ")
pwgen = "$ynEL" + str(pw) + str(last4)
pc.copy(pwgen)
print("\nThe password is $ynEL" + str(pw) + str(last4))
class Application(tk.Frame):
def __init__(self, master=None):
super().__init__(master)
self.quit = tk.Button(self, text="QUIT", fg="black", command=self.master.destroy)
self.quit.grid(row=0,column=0,sticky=tk.EW)
Text.grid(row=1,column=0,sticky=tk.NSEW)
self.b1 = tk.Button(self, text="Generate PW", command=pwgen)
self.b1.grid(row=0,column=1,sticky=tk.EW)
self.grid(row=0,column=0,sticky=tk.NSEW)
app = Application(master=root)
root.mainloop()
A previous version created multiple Generate PW buttons.

Python time app, with tkinter not working

I tried making a basic time application, but, it doesn't work. If you run it, it displays the gui, the no button works (by closing the window). But, the yes button doesn't create a popup telling you the time.
from tkinter import Tk, Label, Button
from datetime import datetime
LARGE_FONT = ("Verdana", 12)
NORM_FONT = ("Helvetica", 10)
SMALL_FONT = ("Helvetica", 8)
class CurrentTime:
def __init__(self, master):
self.master = master
master.title("Current Time")
self.label = Label(master, text="Do you want to know the current time? Y/N", font=LARGE_FONT)
self.label.pack(side="top", fill="x", pady=10, padx=11)
self.time_button = Button(master, text="Yes", command=self.thetime, font=NORM_FONT)
self.time_button.pack(side="top", fill="x", pady=10, padx=11)
self.close_button = Button(master, text="No", command=master.quit, font=NORM_FONT)
self.close_button.pack(side="top", fill="x", pady=10, padx=11)
def thetime(self, master):
now = datetime.now()
current_time = now.strftime("%H:%M:%S")
master.tile("Current Time")
self.label = Label(master, text="Current Time =", command=current_time, font=LARGE_FONT)
self.label.pack(side="top", fill="x", pady=10)
self.close_button = Button(master, text="Okay", command=master.quit, font=NORM_FONT)
self.close_button.pack(side="top", fill="x", pady=10, padx=11)
root = Tk()
yes = CurrentTime(root)
root.mainloop()
Thank you for your help!
You have extra argument master in def thetime(self, master). Remove the extra argument. Also you do not need to recreate the self.label and self.close_button in the function, just update their text is enough:
def thetime(self):
self.time_button.destroy() # remove the 'Yes' button
current_time = datetime.now().strftime("%H:%M:%S")
self.label.config(text="Current Time = "+current_time) # show the current time
self.close_button.config(text="Okay") # change close_button text to 'Okay'

opening a new gui from the gui

updated code as per below comments
I'm struggling to get my top level to open on button press!
I've scanned the code on here but don't seem to be able to get a woking solution. My latest error is:
AttributeError: '_tkinter.tkapp' object has no attribute 'unavail'
from tkinter import *
from ScheduleApi import flightData
import config
from itinerary import fltCreate
class FrontEnd:
def __init__(self, master):
self.master = master
master.title("A simple GUI")
self.label = Label(master, text="This is our first GUI!")
self.label.grid()
self.greet_button = Button(master, text="Create Itinerary", command=self.ItinBuilder)
self.greet_button.grid(row=1)
self.close_button = Button(master, text="Close", command=master.quit)
self.close_button.grid(row=2)
def greet(self):
print("Greetings!")
def ItinBuilder(self):
self = Toplevel(self.master)
self.title ("Please build your itinerary")
self.addflt_button = Button(self.master, text="add flights", command=fltCreate)
self.addflt_button.grid(row=1)
self.addfhtl_button = Button(self.master, text="add hotel", command=self.master.unavail)
self.addflt_button.grid(row=1, column=1)
self.addfmsc_button = Button(self.master, text="add misc item", command=self.master.unavail)
self.addflt_button.grid(row=2, column=1)
self.prvitin_button = Button(self.master, text="preview", command=self.master.unavail)
self.addflt_button.grid(row=2, column=1)
def unavail(self, Toplevel):
print("Function not yet available.")
root = Tk()
my_gui = FrontEnd(root)
root.mainloop()
Please change your function ItinBuilder to this. I hope this is what you expect.
def ItinBuilder(self):
self.newWindow = Toplevel(self.master)
self.newWindow.title ("Please build your itinerary")
self.addflt_button = Button(self.newWindow, text="add flights", command=fltCreate)
self.addflt_button.grid(row=0)
self.addfhtl_button = Button(self.newWindow, text="add hotel", command=self.master.unavail)
self.addfhtl_button.grid(row=0, column=1)
self.addfmsc_button = Button(self.newWindow, text="add misc item", command=self.master.unavail)
self.addfmsc_button.grid(row=1, column=0)
self.prvitin_button = Button(self.newWindow, text="preview", command=self.master.unavail)
self.prvitin_button.grid(row=1, column=1)
The add flights button is in main GUI because you passed the reference to your main window self.master as first argument(called parent in tkinter) in your code.
Only add_flights button is seen and not others because you called grid method only for self.addflt_button and not for other buttons(missed to change variable names in other calls I guess).

Tkinter using append to print to a label

I have been trying to return the fuction printLabel to print "Hello
world!", but I am not too sure how to progress further:
I would like to use lambda in order to print my append strings in the label when the button is clicked but this displays without the button being clicked. My
code is as follows:
from tkinter import *
class Example(Frame):
def printLabel(self):
self.hello = []
self.hello.append('Hello\n')
self.hello.append('World!')
print(self.hello)
return(self.hello)
def __init__(self, root):
Frame.__init__(self, root)
self.buttonA()
self.viewingPanel()
def buttonA(self):
self.firstPage = Button(self, text="Print Text", bd=1, anchor=CENTER, height = 13, width = 13, command=lambda: self.printLabel())
self.firstPage.place(x=0, y=0)
def viewingPanel(self):
self.panelA = Label(self, bg='white', width=65, height=13, padx=3, pady=3, anchor=CENTER, text="{}".format(self.printLabel()))
self.panelA.place(x=100, y=0)
def main():
root = Tk()
root.title("Tk")
root.geometry('565x205')
app = Example(root)
app.pack(expand=True, fill=BOTH)
root.mainloop()
if __name__ == '__main__':
main()
I made a few modifications to your code, and it should work the way you want:
from tkinter import *
class Example(Frame):
def printLabel(self):
self.hello.append('Hello\n')
self.hello.append('World!')
return(self.hello)
# Added 'updatePanel' method which updates the label in every button press.
def updatePanel(self):
self.panelA.config(text=str(self.printLabel()))
# Added 'hello' list and 'panelA' label in the constructor.
def __init__(self, root):
self.hello = []
self.panelA = None
Frame.__init__(self, root)
self.buttonA()
self.viewingPanel()
# Changed the method to be executed on button press to 'self.updatePanel()'.
def buttonA(self):
self.firstPage = Button(self, text="Print Text", bd=1, anchor=CENTER, height = 13, width = 13, command=lambda: self.updatePanel())
self.firstPage.place(x=0, y=0)
# Changed text string to be empty.
def viewingPanel(self):
self.panelA = Label(self, bg='white', width=65, height=13, padx=3, pady=3, anchor=CENTER, text="")
self.panelA.place(x=100, y=0)
def main():
root = Tk()
root.title("Tk")
root.geometry('565x205')
app = Example(root)
app.pack(expand=True, fill=BOTH)
root.mainloop()
if __name__ == '__main__':
main()

Nothing coming up in a GUI (Tkinter) window

I am writing a code for a login system using tkinter and for some reason when I run the code there are no error messages and a window pops up but without the title, buttons or labels I need.
from tkinter import *
import tkinter.messagebox
frame = Tk()
def adminlogincheck(self, master):
frame = Frame(master)
frame.pack()
if username == '123key' and password == 'key123':
accept = Label(frame, text='Login Successful')
else:
decline = Label(frame, text='Login incorrect')
mainloop()
def adminselect(self, master):
frame = Frame(master)
frame.pack()
self.button = Button(frame, text="Cancel", fg="red", command=quit)
self.button.pack(side=LEFT)
self.slogan = Button(frame, text="Proceed", command=self.adminlogin)
self.slogan.pack(side=LEFT)
mainloop()
def adminlogin(self, master):
frame = Frame(master)
frame.pack()
username_entry = Entry(frame)
password_entry = Entrey(frame)
confirm = Button(frame, text='Login', command = adminlogincheck)
loginquit = Button(frame, text='Cancel', command=quit)
mainloop()
I will add more after the login system works but does anyone know why no buttons or labels appear?
There's enough in your request to see what you're trying to accomplish, but there are many issues with the code. Here is a working model of what you appear to be working toward...
from tkinter import *
import tkinter.messagebox
class Admin:
def __init__(self, master):
self.frame = Frame(master)
self.frame.pack()
self.username = StringVar()
self.password = StringVar()
def logincheck(self):
self.clearframe()
if self.username.get() == '123key' and self.password.get() == 'key123':
accept = Label(self.frame, text='Login Successful')
accept.pack(side=LEFT)
else:
decline = Label(self.frame, text='Login incorrect')
decline.pack(side=LEFT)
def select(self):
self.clearframe()
self.button = Button(self.frame, text="Cancel", fg="red", command=quit)
self.button.pack(side=LEFT)
self.slogan = Button(self.frame, text="Proceed", command=self.adminlogin)
self.slogan.pack(side=LEFT)
def login(self):
self.clearframe()
username_entry = Entry(self.frame, textvariable=self.username)
username_entry.pack()
password_entry = Entry(self.frame, textvariable=self.password)
password_entry.pack()
confirm = Button(self.frame, text='Login', command = self.logincheck)
confirm.pack()
loginquit = Button(self.frame, text='Cancel', command=quit)
loginquit.pack()
def clearframe(self):
# Destroy all children of the class's frame.
for child in self.frame.winfo_children():
child.destroy()
root = Tk()
admin = Admin(root)
admin.login()
mainloop()

Categories