0

My code currently checks the username and password entered my the user and then returns to the label with the corresponding text.

As shown below:

from tkinter import *

def Login():
    global AnameEL
    global ApwordEL # More globals :D
    global ArootA
    global f1
    global f2

    ArootA = Tk() # This now makes a new window.
    ArootA.geometry('1280x720')
    ArootA.title('Admin login') # This makes the window title 'login'

    f1 = Frame(width=200, height=200, background="#D3D3D3")
    f2 = Frame(ArootA, width=400, height=200)

    f1.pack(fill="both", expand=True, padx=0, pady=0)
    f2.place(in_=f1, anchor="c", relx=.5, rely=.5)

    AnameL = Label(f2, text='Username: ') # More labels
    ApwordL = Label(f2, text='Password: ') # ^
    AnameL.grid(row=1, sticky=W)
    ApwordL.grid(row=2, sticky=W)

    AnameEL = Entry(f2) # The entry input
    ApwordEL = Entry(f2, show='*')
    AnameEL.grid(row=1, column=1)
    ApwordEL.grid(row=2, column=1)

    AloginB = Button(f2, text='Login', command=CheckLogin) # This makes the login button, which will go to the CheckLogin def.
    AloginB.grid(columnspan=2, sticky=W)

    ArootA.mainloop()

def CheckLogin():
    checkP = Label(f2, text='')
    checkP.grid(row=3, column=1)
    if AnameEL.get() == "test" and ApwordEL.get() == "123": # Checks to see if you entered the correct data.
        checkP.config(text='sucess')

    else:
        checkP.config(text='fail')

Login()

I would like to add another feature where after 2 seconds new lines of code are ran depending on the login failed/success.

For example when the user enters a wrong login I would like the text "fail" to disappear after 2 seconds and if the user enters the correct password I would like a new function to be ran after 2 seconds of the "success" being displayed.

So I tried this: (also importing time at the top of my code)

if AnameEL.get() == "test" and ApwordEL.get() == "123": # Checks to see if you entered the correct data.
    checkP.config(text='sucess')
    time.sleep(2)
    nextpage()
else:
    checkP.config(text='fail')
    time.sleep(2)
    checkP.config(text='')

def nextpage():
    f1.destroy()

However, this wasn't successful. After the login button was pressed it waited 2 seconds and then ran nextpage() instead of displaying "success" for 2 seconds and then running nextpage() and for incorrect logins it goes straight to checkP.config(text='') after 2 seconds of the button press.

How can I resolve this?

All help is appreciated, Thanks.

qtt qtt
  • 187
  • 3
  • 5
  • 19

1 Answers1

1

You need to update root before using time.sleep(). Additionally, since you are dealing with a GUI, you should prefer using timers over pausing execution. In this case, Tkinter's own after() function should be preferred over time.sleep(), because it simply places the event on the event queue as opposed to pausing execution.

after(delay_ms, callback=None, *args)

Registers an alarm callback that is called after a given time.

So, per your example:

if AnameEL.get() == "test" and ApwordEL.get() == "123":
    checkP.config(text='sucess')
    ArootA.update()
    time.sleep(2)
    nextpage()
else:
    checkP.config(text='fail')
    ArootA.update()
    time.sleep(2)
    nextpage()

With after():

if AnameEL.get() == "test" and ApwordEL.get() == "123":
    checkP.config(text='sucess')
    ArootA.after(2000, nextpage)
else:
    checkP.config(text='fail')
    ArootA.after(2000, lambda : checkP.config(text=''))

You may also want to take a look at alternative ways to update the values of labels to avoid having to update root while you are in the mainloop (e.g. Making python/tkinter label widget update?).

Zach Kramer
  • 183
  • 1
  • 1
  • 7
  • 1
    If you're using `after`, you don't need to call `update()`. Also, you're using `after` incorrectly. You must pass `after` a _reference_ to a function. You're immediately calling the function and giving `after` the _result_ of the function. It needs to be `ArootA.after(2000, nextpage)` – Bryan Oakley Dec 17 '17 at 14:50
  • Ah, yes, thank you. I thought `after()` didn't need `update()` but couldn't get it to run without `update()`. Forgot to remove the parentheses! Updated the answer. Good catch. – Zach Kramer Dec 17 '17 at 14:58