我正在使用多个Text小部件在Tkinter中制作一个应用,并且正在使用由KeyPress事件触发的撤消/重做功能。 (我没有使用文本小部件的内置撤消堆栈,因为我有非tkinter对象,它们也可以撤消/重做,并且我想将所有内容都放在一个堆栈中)

在开始之前,我先阅读了给我印象印象的教程和文档(例如http://effbot.org/tkinterbook/tkinter-events-and-bindings.htm)。如果按下的键是``特殊''键而不是字母数字/标点符号,则char为空或None。

实际上并非如此。在键盘上按Backspace键(我使用的是运行El Capitan的Macbook Air)会返回\ x7f的event.char。

阅读有关Tcl/TK的更多信息后,我还了解到X按键符号的列表在平台之间是不一致的,例如在我的Mac上,Shift键的键符号代码显然为0。这意味着我的应用程序将不可打印的字符(如Delete或Shift键)解释为可打印的字符,这与我的实现有些困惑。

无论如何,我将分别处理常见的不可打印键的KeyPress事件,但是出于两个原因,我仍然担心意外的键盘事件行为:1)我的程序打算使用多平台,并且2)使用非美国键盘的人将使用该程序。

我当前使用this作为引用的解决方案是检查event.keysym_num,以查看它是否在可打印字符所使用的键符编号/键代码的范围内。

这是示例代码:

from tkinter import *
from tkinter import ttk

root = Tk()

textbox = Text(root, width=60, height=3)
textbox.grid(sticky=(N, S, E, W))

def KeyboardEvent(event):
    if event.keysym_num > 0 and event.keysym_num < 60000:
        print('This is a printable key. The character is: %r keysym: %r' % \
            (event.char, event.keysym_num))
    else:
        print('This key is unprintable. The character is: %r keysym: %r' % \
            (event.char, event.keysym_num))
textbox.bind('<KeyPress>', KeyboardEvent)
root.mainloop()

我的问题:
  • 我当前的方法是否可以使用,还是有仍然无法使用的不可打印的键?
  • 除了在Tkinter/Python中可打印的按键事件之外,还有更好的方法来区分不可打印的按键事件吗? (我考虑过使用unicodecategory或curses.ascii.isprint(),但每次用户按下一个键时都会进行此检查,因此这些操作看起来像是过分杀了)
  • 我应该注意的KeyPress事件是否还有其他陷阱,尤其是Windows/Mac/Linux之间的不一致行为? (注意:我已经意识到空格字符(例如制表符和回车符)的问题)

  • 我在Mac上使用Python 3(与Homebrew一起安装)。谢谢!

    最佳答案

    问题1和2:

    我相信您的方法有效,但是仅使用str.isprintable方法似乎更简单,它返回一个 bool(boolean) 值,指示参数字符串是否可打印:

    >>> "aéûβß\\".isprintable() #Works with various accents, special characters
    True
    >>> "\x16".isprintable()
    False
    >>> "\n".isprintable() #Excludes all other characters
    False
    

    使用len(repr(event.char) == 3的方法可以工作,但是例如,它也可以排除\,它的代表字符数为4个字符('\\')。

    问题3:

    如您所说,有一堆陷阱(例如:tab的事件char为“\ t”,返回值为“\ r” ...我不知道在哪里/是否可以找到这些特殊性的详尽列表,我唯一有过的解决方案就是尝试使用最常见的解决方案(例如,使用程序,几乎是键盘上的每个键和组合键Ctrl +键):
    chars = dict()
    def LogKey(event, chars = chars): #dict is mutable
        global char #get the actual value of char
        dict[char] = event.char #
    
    root = Tk()
    root.bind("<KeyPress>", LogKey)
    
    for character in "abcde...123456...²&é\"'(-è_...)": #and so on
        char = character
        root.event_generate("<KeyPress-{}>".format(character))
        char = "<Control-{}>".format(character)
        root.event_generate(char)
        char = "<Control-Shift-{}>".format(character)
        ...
    #Inspect the dictonary chars in the end
    

    这可能不是最好的方法,但是它应该涵盖大多数情况,您还可以扩展以测试多个键(例如Control-c-v)...

    07-24 19:38