【发布时间】:2016-10-19 16:03:34
【问题描述】:
我正在使用多个 Text 小部件在 Tkinter 中制作应用程序,并且我正在开发由 KeyPress 事件触发的撤消/重做功能。 (我没有使用文本小部件的内置撤消堆栈,因为我有非 tkinter 对象,它们也可以撤消/重做,我想将所有内容保存在一个堆栈中)
在开始之前,我阅读了教程和文档(例如http://effbot.org/tkinterbook/tkinter-events-and-bindings.htm),这让我觉得如果按下的键是“特殊”键而不是字母数字/标点符号键,则 event.char 将为空或 None。
实际情况并非如此。在我的键盘上按 Backspace(我使用的是运行 El Capitan 的 Macbook Air)返回一个 event.char 为 \x7f。
阅读有关 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 安装)。谢谢!
【问题讨论】:
-
if len(repr(event.char)) == 3:呢?转换为 alt 代码的任何内容都将具有更长的表示形式,并且任何非字符的长度都为 2'' -
使用键绑定执行此操作很重要,或者如果您可以在向小部件中插入或删除某些内容时获得回调,它是否同样有效?如果您要考虑不同的语言和键盘,撤消操作会很棘手。
-
@TadhgMcDonald-Jensen 我考虑过,但不确定它是否有效。 (我用过不少 Python,但没有接受过正式培训,所以不太确定 repr 是如何工作的)
-
@BryanOakley 我有这样的印象,我可能不用键绑定就可以做到,但这是我的第一个主要的 Tkinter 应用程序,一个概念证明,我正在独自开发它,所以我走上了道路- 目前的阻力最小。如果它变得足够流行以拥有非拉丁语言用户,那么我希望到那时有经验(以及时间和金钱:D)来改进它或重新开发整个事物,例如一个网络应用程序。谢谢!
-
我不明白你的回复。我可以提供一个解决方案,在插入或删除任何内容时给你一个回调;你对那种解决方案感兴趣吗?我不知道这对你是否有用。