0

My question is based on this post: (Interactively validating Entry widget content in tkinter). I want to check the input of my entry which is not allowed to be <= 500000. The following code works fine but doesn't give the user proper feedback. Is there a more elegant way to tell the user the entered value is not allowed?

import tkinter as tk


class MyEntry(tk.Frame):
    """frame for trigger settings of a Case tab"""

    def __init__(self, parent):
        tk.Frame.__init__(self, parent)
        # for input checking
        validate_5e4 = self.register(self.validate_int50k)
        self.entry = tk.Entry(parent, textvariable=tk.StringVar(), validate="all",
                              validatecommand=(validate_5e4, "%d", "%P"))
        self.entry.grid(row=0, column=0)

    def validate_int50k(self, insert, string):
        """limits the entry field to only accept int <= 5e4 as input"""
        if insert == "1":
            if string.isdigit():
                try:
                    var = float(string)
                    if var <= 50000:
                        return True
                    else:
                        return False
                except ValueError:
                    self.bell()
                    return False
            else:
                self.bell()
                return False
        else:
            return True


root = tk.Tk()
app = MyEntry(root)
app.mainloop()
KaaraT
  • 90
  • 6
  • You could use tkinter messagebox for your user. Look at [this](https://docs.python.org/3/library/tkinter.messagebox.html) – Rory Apr 26 '22 at 15:50
  • I use messageboxes to display errors but don't think they are the right tool here and would be rather annoying. I have a more subtle way postet as an answer :) – KaaraT Apr 26 '22 at 16:23

1 Answers1

0

To answer my own question for now: I used a ToolTip (https://stackoverflow.com/a/56749167/18794189) to guide the user with their input. This is a good enough solution for me and I hope it will be for you too :)

import tkinter as tk

class ToolTip(object):
    def __init__(self, widget):
        self.text = None
        self.widget = widget
        self.tipwindow = None
        self.id = None
        self.x = self.y = 0

    def showtip(self, text):
        """Display text in tooltip window"""
        self.text = text
        if self.tipwindow or not self.text:
            return
        x, y, cx, cy = self.widget.bbox("insert")
        x = x + self.widget.winfo_rootx() + 57
        y = y + cy + self.widget.winfo_rooty() + 27
        self.tipwindow = tw = tk.Toplevel(self.widget)
        tw.wm_overrideredirect(True)
        tw.wm_geometry("+%d+%d" % (x, y))
        label = tk.Label(tw, text=self.text, justify=tk.LEFT, background="#ffffe0", relief=tk.SOLID, borderwidth=1)
        label.pack(ipadx=1)

    def hidetip(self):
        tw = self.tipwindow
        self.tipwindow = None
        if tw:
            tw.destroy()


def CreateToolTip(widget, text):
    """Create a tip which gets displayed upon hovering to help the user with inputs"""
    toolTip = ToolTip(widget)

    def enter(event):
        toolTip.showtip(text)

    def leave(event):
        toolTip.hidetip()

    widget.bind('<Enter>', enter)
    widget.bind('<Leave>', leave)

To create ToolTips:

entry = tk.Entry(root)
entry.pack()
CreateToolTip(entry, text = "Your tip for the user")
KaaraT
  • 90
  • 6