python - 如何为 ttk.Entry 小部件注册 @staticmethod 密码检查器回调?

标签 python tkinter

我编写了一个密码强度检查器,它可以动态检查键入 ttk.Entry 小部件的密码强度。我已经申请了 criteria通过@ePi272314 和 tutorial on adding validation通过 @ByranOakley 到 ttk.Entry 小部件。下面给出了用于此密码强度检查 ttk.Entry 小部件的 python 脚本,它可以正常工作。

目前,我喜欢将方法 _passwordStrength() 表示为 @staticmethod 以便其他类可以使用它。为此,我需要将 self.pwstrength,一个 tk.StringVar() 传递给它。另外,我需要在注册 @staticmethod 时包含此 tk.StringVar。但是,我很难实现这一点。

我试过类似的方法:

vcmd = (self.register(lambda:App._passwordStrength(self.pwstrength),'%P')) 

但收到错误消息:

Exception in Tkinter callback
Traceback (most recent call last):
  File "/usr/lib/python3.5/tkinter/__init__.py", line 1552, in __call__
    args = self.subst(*args)
TypeError: 'str' object is not callable

感谢有关如何在包含 tk.StringVar 输入参数时注册 @staticmethod _passwordStrength() 的指导。

Python 脚本:

import tkinter as tk
import tkinter.ttk as ttk
import re


class App(ttk.Frame):

    def __init__(self, parent=None, *args, **kwargs):

        ttk.Frame.__init__(self, parent, style='self.TFrame')

        self.style=ttk.Style()
        self.style.configure('self.TFrame', background='pink', borderwidth=10,
                             relief='raised')

        self.pwstrength = tk.StringVar()

        label = ttk.Label(self, text="Password:   ")

        vcmd = (self.register(self._passwordStrength), '%P')
        ePassword = ttk.Entry(self, validate="key", validatecommand=vcmd)
        warnLabel = ttk.Label(self, textvariable=self.pwstrength)

        label.grid(row=0, column=0, sticky='w', padx=20, pady=20)
        ePassword.grid(row=0, column=1, sticky='w')
        warnLabel.grid(row=1, column=1, sticky='w')      


    def _passwordStrength(self, P):
        '''Check password strength.

        A password is considered strong if:
            8 characters length or more
            1 digit or more
            1 symbol or more
            1 uppercase letter or more
            1 lowercase letter or more'''

        password = P
        print (password, len(password))

        # check length
        if password == '':
            self.pwstrength.set('')
            return True

        # check length
        if len(password) < 8:
            self.pwstrength.set('Password is too short')
            return True

        # check for digits
        if not re.search(r"\d", password):
            self.pwstrength.set('Password missing a number.')
            return True

        # check for uppercase
        if not re.search(r"[A-Z]", password):
            self.pwstrength.set('Password missing upper case letter.')
            return True

        # check for lowercase
        if not re.search(r"[a-z]", password):
            self.pwstrength.set('Password missing lower case letter.')
            return True

        # check for symbols
        if not re.search(r"\W", password):
            self.pwstrength.set('Password missing a symbol.')
            return True

        # Passed all checks.
        self.pwstrength.set('Strong password provided.')
        return True



if __name__=='__main__':
    root = tk.Tk()
    root.geometry('300x300+700+250')
    root.title('Password Strength Check')

    app=App(root)
    app.grid(row=0, column=0, sticky='nsew')

    root.rowconfigure(0, weight=1)
    root.columnconfigure(0, weight=1)

    root.mainloop()

最佳答案

您可以通过修改 _passwordStrength() 函数来接受 tk.StringVar 参数以及 functools.partial 来实现。将它提供给现在的静态函数(它不能引用 self.pwstrength 因为它不再是带有 self 参数的常规方法)。

我的意思是:

import functools
import tkinter as tk
import tkinter.ttk as ttk
import re

class App(ttk.Frame):

    def __init__(self, parent=None, *args, **kwargs):

        ttk.Frame.__init__(self, parent, style='self.TFrame')

        self.style=ttk.Style()
        self.style.configure('self.TFrame', background='pink', borderwidth=10,
                             relief='raised')

        self.pwstrength = tk.StringVar()

        label = ttk.Label(self, text="Password:   ")

#        vcmd = (self.register(self._passwordStrength), '%P')
        valcommand = self.register(
                        functools.partial(App._passwordStrength, self.pwstrength)
                     )
        vcmd = (valcommand, '%P')
        ePassword = ttk.Entry(self, validate="key", validatecommand=vcmd)
        warnLabel = ttk.Label(self, textvariable=self.pwstrength)

        label.grid(row=0, column=0, sticky='w', padx=20, pady=20)
        ePassword.grid(row=0, column=1, sticky='w')
        warnLabel.grid(row=1, column=1, sticky='w')

    @staticmethod
    def _passwordStrength(svar, P):
        '''Check password strength.

        A password is considered strong if:
            8 characters length or more
            1 digit or more
            1 symbol or more
            1 uppercase letter or more
            1 lowercase letter or more'''

        password = P
        print (password, len(password))

        # check length
        if password == '':
            svar.set('')
            return True

        # check length
        if len(password) < 8:
            svar.set('Password is too short')
            return True

        # check for digits
        if not re.search(r"\d", password):
            svar.set('Password missing a number.')
            return True

        # check for uppercase
        if not re.search(r"[A-Z]", password):
            svar.set('Password missing upper case letter.')
            return True

        # check for lowercase
        if not re.search(r"[a-z]", password):
            svar.set('Password missing lower case letter.')
            return True

        # check for symbols
        if not re.search(r"\W", password):
            svar.set('Password missing a symbol.')
            return True

        # Passed all checks.
        svar.set('Strong password provided.')
        return True



if __name__=='__main__':
    root = tk.Tk()
    root.geometry('300x300+700+250')
    root.title('Password Strength Check')

    app=App(root)
    app.grid(row=0, column=0, sticky='nsew')

    root.rowconfigure(0, weight=1)
    root.columnconfigure(0, weight=1)

    root.mainloop()

关于python - 如何为 ttk.Entry 小部件注册 @staticmethod 密码检查器回调?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49281416/

相关文章:

python - Beautifulsoup 多个div内容到字典

python - 单击按钮并将当前时间和默认值保存在数据库中(Django)

python - 按特定顺序格式化字符串

python - python 2.7 上的 Ttk

python - 下拉菜单启动功能

python-2.7 - 如何为 tktable 的每一列设置不同的列宽?

python - 如何将 python 代码转换为解析树并返回原始代码?

python - Tkinter:多显示器问题

python - 当单击而不是 shell 时,如何使按钮的值显示到 tkinter 上?

python - 在python中根据终端宽度制表?