我正在使用多个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()
我的问题:
我在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)...