Home > other >  Messagebox in ttk.Spinbox bound command causes an infinite stream of pop up windows
Messagebox in ttk.Spinbox bound command causes an infinite stream of pop up windows

Time:02-11

I am working on a personal learning project that consists in a simple GUI that generates passwords. The user can either select how many characters of each type (letters, numbers and symbols) to include in the password or simply let the application choose a random combination. There is a password length constraint of 128 characters. What I am trying to do is to show a message when the user tries to increase the number of characters beyond the 128 limit.

What I've tried so far is to include a check in the function bound to the <<Increment>> event that gets called when the increment button in the spinbox is pressed. There is an if statement that checks the available characters left, if the value is zero then a messagebox.showwarnning pops up informing the user that the maximum amount of chars is 128.

The message appears but when the ok button is clicked the message closes just to pop up again and again and the only way to stop it is to kill the whole thing. I have also tried to move the messagebox to the function that is bound to the spinbox command with the same result. Any ideas on how to solve this or what am I doing terribly wrong? Thanks

This is a simplify version of the widget:

from tkinter import *
from tkinter import ttk
from tkinter import messagebox


class App(Tk):
    def __init__(self):
        super().__init__()
        self.title('Sample')
        self.geometry('300x100')
        Selector(self).pack()

class Selector(ttk.Frame):
        def __init__(self, container):
            super().__init__(container)
            self.max_length = 10
            self.input = IntVar(0);

            self.label = ttk.Label(self, text="Quantity: ").pack()
            self.spinbox = ttk.Spinbox(self, from_=0,
                                       to=self.max_length,
                                       textvariable=self.input)
            self.spinbox.pack()
            self.spinbox.bind('<<Increment>>', lambda e: self.check_length(e))

        def check_length(self, e):
            if self.input.get() == 10:
                messagebox.showwarning("Max length reached", "Too much!")
            

        
if __name__ == "__main__":
    app = App()
    app.mainloop()

CodePudding user response:

It seems that closing the messagebox retriggers the <<Increment>> event. I think I have found a workaround: the focus is removed from the spinbox after closing the messagebox and the value of the spinbox is checked only if the spinbox has the focus (which means that the user has actually clicked on it).

from tkinter import *
from tkinter import ttk
from tkinter import messagebox


class App(Tk):
    def __init__(self):
        super().__init__()
        self.title('Sample')
        self.geometry('300x100')
        Selector(self).pack()

class Selector(ttk.Frame):
        def __init__(self, container):
            super().__init__(container)
            self.max_length = 10
            self.input = IntVar(self, 0);

            self.label = ttk.Label(self, text="Quantity: ").pack()
            self.spinbox = ttk.Spinbox(self, from_=0,
                                       to=self.max_length,
                                       textvariable=self.input)
            self.spinbox.pack()
            self.spinbox.bind('<<Increment>>', lambda e: self.check_length(e))

        def check_length(self, e):
            if str(self.spinbox) != str(self.focus_get()):
                return
            if self.input.get() == 10:
                messagebox.showwarning("Max length reached", "Too much!")
                self.focus_set()



if __name__ == "__main__":
    app = App()
    app.mainloop()

Note: This does not solve the underlying problem (the fact that <<Increment>> is endlessly triggered after closing the messagebox), it only prevents the endless reopening of the messagebox.

  • Related