Help with <key> event in python Entry widget

I'm writing some code in python and I'm having trouble when trying to retrieve content of an Entry widget. The thing is: I want to limit the characters that can be typed, so I'm trying to clear the Entry widget when I reach the specific number of characters (2 in this case), but it looks like I always miss the last typed character. I added the lost character in a print to show.

Here's the sample code:

from Tkinter import *
class sampleFrame:
    def __init__(self, master):
        self.__frame = Frame(master)
        self.__frame.pack()
    def get_frame(self):
        return self.__frame


class sampleClass:
    def __init__(self, master):
        self.__aLabel = Label(master,text="aLabel", width=10)
        self.__aLabel.pack(side=LEFT)
        self.__aEntry = Entry (master, width=2)
        self.__aEntry.bind('<Key>', lambda event: self.callback(event, self.__aEntry))
        self.__aEntry.pack(side=LEFT)

    def callback(self, event, widgetName):
        self.__value = widgetName.get()+event.char
        print self.__value
        if len(self.__value)>2:
            widgetName.delete(2,4)





root = Tk()
aSampleFrame = sampleFrame(root)
aSampleClass = sampleClass(aSampleFrame.get_frame())
root.mainloop()

Any help will be much appreciated!

Thanks in advance


Asked by: Carina685 | Posted: 01-10-2021






Answer 1

At first, after you do the deletion, the event goes on with its normal processing, i.e. the character gets inserted. You need to signal to Tkinter that the event should be ignored.

So in your code above, add the marked line:

if len(self.__value) > 2:
    widgetName.delete(2,4)
    return "break" # add this line

On the other hand, why do you go through the lambda? An event has a .widget attribute which you can use. So you can change your code into:

    self.__aEntry.bind('<Key>', self.callback) # ※ here!
    self.__aEntry.pack(side=LEFT)

def callback(self, event):
    self.__value = event.widget.get()+event.char # ※ here!
    print self.__value
    if len(self.__value)>2:
        event.widget.delete(2,4) # ※ here!
        return "break"

All the changed lines are marked with "here!"

Answered by: Dainton653 | Posted: 02-11-2021



Answer 2

To be a bit more specific, Tk widgets have what are called "bindtags". When an event is processed, each bindtag on the widget is considered in order to see if it has a binding. A widget by default will have as its bindtags the widget, the widget class, the root widget, and "all". Thus, bindings to the widget will occur before the default bindings. Once your binding has been processed you can prevent any further bindtags from being considered by returning a "break".

The ramifications are this: if you make a binding on the widget, the class, root window and "all" bindings may fire as well. In addition, any binding you attach to the widget fires before the class binding which is where the default behavior (eg: the insertion of a character) happens. It is important to be aware of that in situations where you may want to handle the event after the default behavior rather than before.

Answered by: Sawyer871 | Posted: 02-11-2021



Similar questions

python - How to use the same widget twice in pygtk?

This doesn't work well: image_log = gtk.Image() image_log.set_from_file("test.png") self.out_button = gtk.Button() self.out_button.add(image_log) self.err_button = gtk.Button() self.err_button.add(image_log) another_box.pack_start(self.out_button, False) another_box.pack_start(self.err_button, False) The problem is, image_log is used twice and GTK doesn't...


python - PyQt4 - Widget Is Not Shown

I've made this program in Python and Qt4. #!/usr/bin/python # -*- coding: utf-8 -*- import sys from PyQt4 import QtGui from PyQt4 import QtCore color = QtGui.QColor(99, 0, 0) class colorButton(QtGui.QWidget): def __init__(self, args): QtGui.QWidget.__init__(self,args) self.setGeometry(150, 22, 50, 50) self.setStyleSheet("QWidget { background-color: %s }" % color.name()) clas...


python Qt: main widget scroll bar

We are trying to put scrollbar on the main widget, so if the user resizes the main window, the scrollbar appears, and let he move up and down to see child widgets that is outside the smaller window widget, allowing it to move right and left. Here is the code for the main widget with the scroll-bar.. def centralWDG(self,MainWindow): self.centralwidget = QtGui.QWidget(MainWindow) self.centralw...


Python GTK+ widget name

How do I get a widget's "name"? When I define a GUI using Glade, I can "name" the widgets of the window but how do I recover that property when I have a widget object instance? I've tried get_property(), get_name() and $widget.name to no avail. Update: I am using GtkBuilder file format (i.e. XML format). Resolution: a f...


python - Bind a widget from inside a class

Every example I've seen on this subject has shown a Button being bound to a command, except the Button widget was being made outside of a class: e.g.: from Tkinter import * root = Tk() def callback(event): print "clicked at", event.x, event.y frame = Frame(root, width=100, height=100) frame.bind("&lt;Button-1&gt;", callback) frame.pack() root.mainloop() Now that's fine, ...


Python Widget that can show both HTML & CSS

I have an idea to create a Parental Supervision Web Browser. The way it works is that I create a desktop application in python(preferably using wxPython or wxPythons webkit) thats just a widget that can display HTML &amp; CSS. HTTP requests for a website will go through a proxy on my server. So if someone wants to access the website "http://google.com": - they type in that url in the python browser - the re...


python - pygtk get widget by name from parent node

I have a gtk widget and I want to find out if within its descendants there is another widget. If there is one, I want to return it otherwise return None. This is a simple recursive problem but I cannot seem to get the right method to do it. In the glade xml file, I have: &lt;object class="GtkDialog" id="monkey"&gt; [...] &lt;object class="GtkTreeView" id="ook"&gt; and...


python - How to use more than one widget in a Django field?

I have a specific field in a form which needs to have a custom attribute AND we styled as a password box. Currently I have: login_password = forms.CharField(label=(u'password')) But I need both of these: widget=forms.TextInput(attrs={'placeholder': 'password'}) widget=forms.PasswordInput(render_value=False) How can I make it so the field uses these two wid...


python - need a time widget or clock widget

is there anything like a timewidget or clock widget in Django which will help me to input data into a form for appointment date (like we have calendar or date widget). i have my date widget working with the below code in my forms.py: import datetime from django.forms.extras.widgets import SelectDateWidget mydate = forms.DateField(widget=SelectDateWidget) is there anything like this...


python - Looking for a child widget with pygtk

Let's explain the enviroment. I'm building a GUI using pygtk. At some point of my code I create a gtk.ScrolledWindow and set it a name (here the code): top_swin = gtk.ScrolledWindow() top_swin.set_name('script-desc-swin') Later on other part of the code I need to look for this widget so I have tried this: self.gui.get_object('script-desc-swin') sel...


python - What's the best Django search app?


How can I use a DLL file from Python?

What is the easiest way to use a DLL file from within Python? Specifically, how can this be done without writing any additional wrapper C++ code to expose the functionality to Python? Native Python functionality is strongly preferred over using a third-party library.


python - PubSub lib for c#

Is there a c# library which provides similar functionality to the Python PubSub library? I think it's kind of an Observer Pattern which allows me to subscribe for messages of a given topic instead of using events.


python - What is the best way to copy a list?

This question already has answers here:


python - Possible Google Riddle?

My friend was given this free google website optimizer tshirt and came to me to try and figure out what the front logo meant. t-shirt So, I have a couple of guesses as to what it means, but I was just wondering if there is something more. My first guess is that eac...


How do you check whether a python method is bound or not?

Given a reference to a method, is there a way to check whether the method is bound to an object or not? Can you also access the instance that it's bound to?


ssh - How to scp in Python?

What's the most pythonic way to scp a file in Python? The only route I'm aware of is os.system('scp "%s" "%s:%s"' % (localfile, remotehost, remotefile) ) which is a hack, and which doesn't work outside Linux-like systems, and which needs help from the Pexpect module to avoid password prompts unless you already have passwordless SSH set up to the remote host. I'm aware of Twisted'...


python - How do I create a new signal in pygtk

I've created a python object, but I want to send signals on it. I made it inherit from gobject.GObject, but there doesn't seem to be any way to create a new signal on my object.


python - What do I need to import to gain access to my models?

I'd like to run a script to populate my database. I'd like to access it through the Django database API. The only problem is that I don't know what I would need to import to gain access to this. How can this be achieved?


python - How do I edit and delete data in Django?

I am using django 1.0 and I have created my models using the example in the Django book. I am able to perform the basic function of adding data; now I need a way of retrieving that data, loading it into a form (change_form?! or something), EDIT it and save it back to the DB. Secondly how do I DELETE the data that's in the DB? i.e. search, select and then delete! Please show me an example of the code ...






Still can't find your answer? Check out these communities...



PySlackers | Full Stack Python | NHS Python | Pythonist Cafe | Hacker Earth | Discord Python



top