Question

I've got a problem with Entry widget while making a copy of Windows Calc.

I have made buttons like in windows calc and I also bind the keyboard 1234567890 + - / * % buttons, to make the same things as the calc buttons. The mainly problem was that I wanted the Entry to store only numbers and let user input only numbers... but after searching many topics about validatecommand and also looking at windows calc I decided that validatecommand isn't the thing I need - I don't know how to make it validate every character the user inputs to the entry box and after making the keyboard binds, when I am in entrybox and press "1" to write the number it does it two times, because the keyboard event binding inserts the "1" to the entry box too.

So, the thing I want to make is to make entry widget work like the Windows Calc.exe entry box. The windows calc entry box doesn't let you insert any other character then numbers and also doesn't let you to put your cursor into the entry box..., it looks like this: -entrybox is disabled BUT it looks like ENABLED -numbers and operations can be made by calc buttons or by keyboard buttons

I tried getting this effect by disabling the entry widget at start, and making all buttons functions like that: -enable the entry widget -insert the number (the widget must be in enabled? or normal? (don't remember the name) state to let you insert something to it) -disable the entry widget

It works like I want... but it doesn't look like I want it to look. Is there any possibility to change Entry widget disabled bg color to normal? Or maybe is there another way to make such entry box? :S

Was it helpful?

Solution

The way to do it is with the validatecommand and validate options of the entry widget. This scenario is precisely what those features are for.

You say you "don't know how to make it validate every character the user inputs to the entry box". If you set the validate attribute to "key", that will cause your validate command to be called on every keypress.

Unfortunately, this is a somewhat under-documented feature of Tkinter, though it's documented quite well for Tk. Here's a working example which performs some very rudimentary checks:

import Tkinter as tk

class SampleApp(tk.Tk):
    def __init__(self):
        tk.Tk.__init__(self)
        # define a command to be called by the validation code.  %P
        # represents the value of the entry widget if the edit is
        # allowed. We want that passed in to our validation comman so
        # we can validate it. For more information see
        # http://tcl.tk/man/tcl8.5/TkCmd/entry.htm#M7
        vcmd = (self.register(self._validate), '%P')
        e = tk.Entry(self, validate="key", validatecommand=vcmd)
        e.pack()

    def _validate(self, P):
        # accept the empty string, "." or "-." (to make it possible to
        # enter something like "-.1"), or any string that can be
        # converted to a floating point number.
        try:
            if P in (".", "-", "-.", ""):
                return True
            n = float(P)
            return True
        except:
            self.bell()
            return False

app=SampleApp()
app.mainloop()

If you search this site for [tkinter] validatecommand you'll find many other examples.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top