1

我正在从事一个个人学习项目,该项目包含一个生成密码的简单 GUI。用户可以选择在密码中包含多少每种类型的字符(字母、数字和符号),或者简单地让应用程序选择一个随机组合。密码长度限制为 128 个字符。我要做的是在用户尝试将字符数增加到超过 128 个限制时显示一条消息。

到目前为止,我尝试的是在绑定到<<Increment>>事件的函数中包含一个检查,该事件在按下旋转框中的增量按钮时被调用。有一个 if 语句检查剩余的可用字符,如果值为零,则弹出 messagebox.showwarnning 通知用户最大字符数为 128。

消息出现,但是当单击确定按钮时,消息关闭只是为了一次又一次地弹出,而停止它的唯一方法是杀死整个事情。我还尝试将消息框移动到绑定到 spinbox 命令的函数,结果相同。关于如何解决这个问题或我做错了什么的任何想法?谢谢

这是小部件的简化版本:

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()
4

1 回答 1

1

似乎关闭消息框会重新触发<<Increment>>事件。我想我找到了一种解决方法:关闭消息框后,焦点从旋转框中移除,并且只有在旋转框具有焦点时才检查旋转框的值(这意味着用户实际上已经点击了它)。

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()

注意:这并不能解决根本问题(<<Increment>>关闭消息框后无限触发的事实),它只会阻止无限重新打开消息框。

于 2022-02-09T11:24:29.183 回答