如何允许每个字符输入一次?

时间:2015-11-15 19:50:58

标签: python tkinter get tkinter-entry

我有一个加密代码,由26个字母组成,还有一个选项,允许用户根据需要进行更改。在多次尝试我的程序后,我遇到了一个错误,一个合乎逻辑的错误。用户可以更改代码,但是,他们可以输入相同的字符26次或至少1个字符不止一次,这可能会破坏我的整个程序。有没有办法只允许用户输入每个字母一次?这是我到目前为止所做的:

import tkinter 

letters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 

encryption_code = 'LFWOAYUISVKMNXPBDCRJTQEGHZ'

letters += letters.lower()
encryption_code += encryption_code.lower() 

window = tkinter.Tk()

encrypt_entry = tkinter.Entry(window)
encrypt_entry.pack()


def code_change(event):
    global encrypt_entry
    global encryption_code

    encryptget = encrypt_entry.get()

    if len(encryptget) == 26:
        print("You have changed the encryption code")
        encryption_code = encryptget
        encryption_code += encryption_code.lower()
        enc = dict(zip(letters, encryption_code)) 
        dec = dict(zip(encryption_code, letters))

    elif len(encryptget) < 26 or len(encryptget) > 26:
        print("Please enter 26 characters")
        encrypt_entry.delete(0, tkinter.END) 

window.bind('<Return>', code_change)

修改 我尝试了以下但是现在如果我尝试输入字母或encryption_code elif语句什么都不做。

import tkinter 

letters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 

encryption_code = 'LFWOAYUISVKMNXPBDCRJTQEGHZ'

letters += letters.lower()
encryption_code += encryption_code.lower() 

window = tkinter.Tk()

encrypt_entry = tkinter.Entry(window)
encrypt_entry.pack()


def code_change(event):
    global encrypt_entry
    global encryption_code

    encryptget = encrypt_entry.get()

    if len(set(encryptget)) == 26 and encryptget != encryption_code and encryptget != letters:
        print("You have changed the encryption code")
        encryption_code = encryptget
        encryption_code += encryption_code.lower()
        enc = dict(zip(letters, encryption_code)) 
        dec = dict(zip(encryption_code, letters))

    elif len(set(encryptget)) != 26 and encryptget == encryption_code and encryptget == letters:
        print("Please enter each character exactly once")
        encrypt_entry.delete(0, tkinter.END)        

window.bind('<Return>', code_change)

2 个答案:

答案 0 :(得分:1)

Tkinter具有专门用于此类验证的功能。您可以让它为每次插入调用一个函数,并且此函数可以根据您想要的任何条件接受或拒绝该插入。

在您的情况下,标准是&#34;没有重复的字符&#34;。确定这一点的简单方法是将字符串转换为集合(根据定义,集合没有重复),然后将集合的长度与字符串的长度进行比较。

要在每次用户按下某个键时调用此函数,请设置条目小部件的validatevalidatecommand选项。还有一个额外的步骤,你必须注册命令,告诉tkinter你希望命令接收几个特殊参数。

解决方案看起来像这样:

# Define a command to be run whenever the user edits the entry
# N.B. d will be "1" for an insert, "0" for delete, and "-1"
# for anything else. P will be the value of the entry if this
# edit is allowed.
#
# Note: this function must always return either True or False
def encryption_validation(d, P):
    if d == "1":   # ie: an insert
        unique_chars = set(P)
        if len(P) > len(unique_chars):
            return False
    return True

# register the command with tkinter
vcmd = (window.register(encryption_validation), '%d', '%P')

# configure the entry widget to use this command
encrypt_entry.configure(validate="key", validatecommand=vcmd)

如上所述,用户不可能两次输入任何字符。请注意,此解决方案还可以防止用户粘贴具有重复字符的字符串。

有关条目验证的详尽解释,请参阅stackoverflow上的以下答案:https://stackoverflow.com/a/4140988/7432

答案 1 :(得分:-1)

如果我弄错了,请纠正我,但听起来你只是想确保用户为代码输入的字符串不包含任何副本?

我个人并不了解验证命令,但我认为这可以达到您的目标:

def IsCodeValid(encryption_code):
    c = [0]*26

    pos = 0
    for i in range(len(encryption_code)):
        pos = ord(encryption_code[i])-ord('A') #find placement relative to A in unicode
        c[pos] = c[pos] + 1 #increment counter for that letter

    j = 0
    ValidCode = True
    while j<26 and ValidCode:
        if c[j]>1: #check to see if any letter occurred more than once
            ValidCode = False
        else:
            j += 1

    return ValidCode

请注意,这也预计所有字母都会输入大写字母。但是你可以通过在接受数据之前规范化数据来解决这个问题。或者,您可以使逻辑复杂化以检查上限和下限。小写。

编辑:假设您不希望在encryption_code无效的情况下运行代码,您可以使用此标志在运行程序的其余部分之前从用户请求新的encryption_code。