Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Binding multiple events on Tkinter Entry?

I want to capture the time(in milliseconds) taken by a person to type a password, that is, from the first key press to the time the person presses Enter button. To accomplish this, I have the following code:

import tkinter as tk
import time

class MyApp(object):
    start=0.0
    end=0.0
    total_time=0.0
    def __init__(self, master):
        self.pass1 = tk.Entry(master,show="*")
        self.pass1.bind('<Key>', self.callback1)
        self.pass1.pack()

    def callback1(self, event): # Called Only by first key press
        self.start=time.time()*1000.0 # start variable must be modified ONLY by  first key press

    def callback2(self,event): # called by Enter Key press
        self.end=time.time()*1000.0
        self.total_time=self.start-self.end
        print(self.totaltime)

root = tk.Tk()
app = MyApp(root)
root.mainloop()

The problem I am having is I am not able to bind callback1and callback2 on pass1. What I wanted was that when a person hit the first key of their password, startis set to the current time and when the person press Enter endis initialized to the current time. I hope these two would give me an approximate of the time.

How can i modify the program above to accomplish what I want? Thanks.

like image 747
CN1002 Avatar asked Dec 01 '15 13:12

CN1002


People also ask

How do I bind the Enter key to a function in Tkinter?

To bind the <Enter> key with an event in Tkinter window, we can use bind('<Return>', callback) by specifying the key and the callback function as the arguments. Once we bind the key to an event, we can get full control over the events.

How do you bind events in Python?

The binding function is used to deal with the events. We can bind Python's Functions and methods to an event as well as we can bind these functions to any particular widget. Code #1: Binding mouse movement with tkinter Frame.

Can a Tkinter button have multiple commands?

The Tkinter button has only one command property so that multiple commands or functions should be wrapped to one function that is bound to this command .


1 Answers

Firstly, you need to bind callback2 to the Enter / Return Key this is done using '<Return>'.

def __init__(self, master):
    self.pass1 = tk.Entry(master,show="*")
    self.pass1.bind('<Key>', self.callback1)
    self.pass1.bind('<Return>', self.callback2) # callback2 bound to Enter / Return key
    self.pass1.pack()

Next, you want to only allow callback1 to run once. To do this, unbind it from the widget like so

def callback1(self, event):
    self.start=time.time()*1000.0 
    self.pass1.unbind('<Key>') # unbind callback1

And then finally rebind it once the Enter key is pressed, so in the callback2 function

def callback2(self,event): # called by Enter Key press
    self.end=time.time()*1000.0
    self.total_time=self.end-self.start
    print(self.total_time)
    self.pass1.bind('<Key>', self.callback1) # rebind callback1

Side Notes:

As you can see I changed the ordering for the time to end - start instead of what you had before which was start - end which gives you a negative value.

I also suggest changing '<Key>' to '<KeyRelease>'

Your other options if you don't want to unbind the function is to use an if statement checking if self.start has a value.

if self.start == 0.0:
    self.start=time.time()*1000.0

You should also put your variables inside the __init__ function.

def __init__(self, master):
    self.start=0.0
    self.end=0.0
    self.total_time=0.0
    ...
like image 174
Steven Summers Avatar answered Oct 17 '22 12:10

Steven Summers