如何在Tkinter中捕获按键事件?

2024-05-28 19:02:43 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个spinbox,其值范围为0-366,这意味着它只允许数字数据类型和退格。每当用户键入字符时,如果它不是数字类型,则会自动删除。我来自C#背景,这是我第一次尝试Python语言。这是我的密码

def validate(event): 
    charPress=event.keysym

    val=sbDays.get() #previous values
    
    if not charPress.isdigit():
        sbDays.config(textvariable=StringVar(windows).set(val))



sbDays=tk.Spinbox(frame,from_=0,to=366,borderwidth=sbBorderWidth)
sbDays.place(relx=initialX,rely=yDistance,relwidth=sbWidth)
sbDays.config(validate='all',validatecommand=(windows.register(validate),'% P'))
sbDays.update()
sbDays.bind('<Key>',validate)

根据上面的代码,当我运行它时,它不会返回任何内容。因为我是C#出身。这就是我真正需要的。这是C#keypress事件

public static void TextBox_KeyPress_NumberBackspace(object sender, KeyPressEventArgs e)
 {
  char keyChar = e.KeyChar;
  if (char.IsNumber(keyChar) || char.IsControl(keyChar))
      e.Handled = false;
  else
      e.Handled = true;
 }

tbDays.KeyPress += TextBox_KeyPress_NumberBackspace;

Tags: eventconfigifwindows数字valvalidatekeypress
1条回答
网友
1楼 · 发布于 2024-05-28 19:02:43

您没有正确使用validatecommand属性。函数不应直接更改值。validatecommand函数的任务是返回TrueFalse。如果返回True,则允许输入,否则将拒绝输入

如果它返回除TrueFalse(包括None)之外的任何其他值,或者如果函数尝试更改该值,则验证函数将被禁用

您可以配置tkinter以发送确定数据是否有效所需的信息。您不应该依赖于get()返回的值,因为这只会返回上一个值,而不是用户输入的值

由于您只希望允许整数,并且希望将该值限制为最大366,因此最好的解决方案是在允许编辑的情况下(使用%P),让tkinter传入该值,然后您可以使用该值确定该值是否有效

您也不应该绑定到<Key>事件,它不需要验证功能,事实上会妨碍它的工作

该函数将如下所示:

def validate(new_value):
    if new_value == "":
        # allow blank entry so user doesn't get frustrated
        # when trying to delete the first character
        return True

    try:
        value = int(float(new_value))
    except ValueError:
        return False
    return value >= 0 and value <= 366

您应该像下面那样配置validatecommand(注意%P之间没有空格):

sbDays.configure(validate='all',validatecommand=(root.register(validate), '%P'))

您可能需要在其他地方添加一些额外的代码来处理边缘情况,即用户删除小部件中的所有内容,而不输入任何其他内容。例如,您可以使用类似value=sbDays.get() or 0的内容

相关问题 更多 >

    热门问题