如何编写通过其相关变量将单击的按钮的编号添加到PIN码条目的功能?

时间:2018-09-22 10:08:05

标签: python tkinter

我正在尝试使用python和tkinter构建虚拟numpad(分别为1,2和3)。

如果我按1(按钮1),那么account_number_entry应该更改为1,如果我按2,那么account_number_entry应该相应地更改。

我尝试过此代码,但是。

    import tkinter as tk
    win = tk.Tk()

    def handle_pin_button(event):
        '''Function to add the number of the button clicked to the PIN number entry via its associated variable.'''
        # Limit to 4 chars in length
        # Set the new pin number on the pin_number_var


    def create_login_screen():
        accLabel = tk.Label(win, text="Acount Number / Pin")
        accLabel.grid(row=1, column=0)

        account_number_var = tk.StringVar()
        account_number_entry = tk.Entry(win, textvariable=account_number_var)
        account_number_entry.grid(row=1, column=1)
        account_number_entry.focus_set()

        pin_number_var = tk.StringVar()
        account_pin_entry = tk.Entry(win, show='*', text='PIN Number', textvariable=pin_number_var)
        account_pin_entry.grid(row=1, column=2)

        # Buttons 1, 2 and 3 here. Buttons are bound to 'handle_pin_button' function via '<Button-1>' event.
        button1 = tk.Button(text="1")
        button1.bind('<Button-1>', handle_pin_button)
        button1.grid(row=2, column=0, sticky="NESW")
        button2 = tk.Button(text="2")
        button2.bind('<Button-1>', handle_pin_button)
        button2.grid(row=2, column=1, sticky="NESW")
        button3 = tk.Button(text="3")
        button3.bind('<Button-1>', handle_pin_button)
        button3.grid(row=2, column=2, sticky="NESW")


    create_login_screen()
    tk.mainloop()

1 个答案:

答案 0 :(得分:0)

您需要在函数create_login_screen()外部创建account_number_var,否则在函数退出时将被垃圾回收。

将按钮绑定到函数的通常方法是使用参数command。当您有一个处理来自许多按钮的回调的函数时,通常的方法是使用lambda

以下示例:

import tkinter as tk
win = tk.Tk()

account_number_var = tk.StringVar() # Create outside function
pin_number_var = tk.StringVar()

def handle_pin_button(digit):
    account_number_var.set(digit)

def create_login_screen():
    accLabel = tk.Label(win, text="Acount Number / Pin")
    accLabel.grid(row=1, column=0)

    account_number_entry = tk.Entry(win, textvariable=account_number_var)
    account_number_entry.grid(row=1, column=1)
    account_number_entry.focus_set()

    account_pin_entry = tk.Entry(win, show='*', text='PIN Number',
                                 textvariable=pin_number_var)
    account_pin_entry.grid(row=1, column=2)

    # Buttons 1, 2 and 3 here. Buttons are bound to 'handle_pin_button' function via '<Button-1>' event.
    button1 = tk.Button(text="1", command=lambda:handle_pin_button("1"))
    button1.grid(row=2, column=0, sticky="NESW")
    button2 = tk.Button(text="2", command=lambda:handle_pin_button("2"))
    button2.grid(row=2, column=1, sticky="NESW")
    button3 = tk.Button(text="3", command=lambda:handle_pin_button("3"))
    button3.grid(row=2, column=2, sticky="NESW")


create_login_screen()
win.mainloop()

如何使用bind()而不是按钮command来做到这一点:

首先,您需要跟踪按钮。由于它们是在函数内部创建的,因此必须在全局范围内保存引用。

第二,必须从列表索引计算按钮值,并相应地设置account_number_var

然后将按钮绑定到回调处理程序。

import tkinter as tk
win = tk.Tk()

account_number_var = tk.StringVar() # Create outside function
pin_number_var = tk.StringVar()
button_list = []    # Global button reference list

def handle_pin_button(event):
    button_number = button_list.index(event.widget) + 1
    account_number_var.set(str(button_number))

def create_login_screen():
    accLabel = tk.Label(win, text="Acount Number / Pin")
    accLabel.grid(row=1, column=0)

    account_number_entry = tk.Entry(win, textvariable=account_number_var)
    account_number_entry.grid(row=1, column=1)
    account_number_entry.focus_set()

    account_pin_entry = tk.Entry(win, show='*', text='PIN Number',
                                 textvariable=pin_number_var)
    account_pin_entry.grid(row=1, column=2)

    # Buttons 1, 2 and 3 here. Buttons are bound to 'handle_pin_button' function via '<Button-1>' event.
    button1 = tk.Button(text="1")
    button1.grid(row=2, column=0, sticky="NESW")
    button1.bind('<Button-1>', handle_pin_button)
    button_list.append(button1) # Add button to global list
    button2 = tk.Button(text="2")
    button2.grid(row=2, column=1, sticky="NESW")
    button2.bind('<Button-1>', handle_pin_button)
    button_list.append(button2) # Add button to global list
    button3 = tk.Button(text="3")
    button3.grid(row=2, column=2, sticky="NESW")
    button3.bind('<Button-1>', handle_pin_button)
    button_list.append(button3) # Add button to global list


create_login_screen()
win.mainloop()