繁体   English   中英

<Key>事件平台的关键代码是否独立?

[英]Are the key codes of a <Key> event platform-independent?

我想为我的文本编辑器创建行号,但它有点复杂: Tkinter在文本小部件中添加行号

所以我决定创建一个行和列计数器,就像在IDLE 为了实现这个目标,我决定监听在tkinter.Text小部件上生成的<Key>事件。 我不知道哪个是事件对象的属性,所以我决定看看Event类的源代码(最好的教程之一:D),我发现有2个主要属性是有趣的我的目标,那就是keycodechar

我的问题是,这个keycodes平台是独立的吗? 我希望我的文本编辑器可以在没有未定义行为的所有平台上工作,因为keycodes解释错误。

这是我想做的一个简单实用的功能示例:

from tkinter import *

lines = 1
columns = 0

ARROWS = (8320768, 8124162, 8255233, 8189699)

def on_key_pressed(event=None):
    global columns, lines

    if event.keycode == 3342463: # return
        if columns > 0 and lines > 0:
            columns -= 1
            if columns < 0: # decrease lines if columns < 0
                columns = 0
                lines -= 1
        if columns == 0 and lines > 1:
            lines -= 1

    elif event.keycode == 2359309: # newline
        columns = 0
        lines += 1
    else:
        if event.keycode not in (ARROWS) and event.char != '':
            columns += 1

    print("Lines =", lines)
    print("Columns =", columns, '\n\n')
    print(event.keycode, ' = ', repr(event.char))

root = Tk()

text = Text(root)

text.pack(fill='both', expand=1)
text.bind('<Key>', on_key_pressed)

root.mainloop()

这种方法有什么问题(在回答我的第一个问题后)?

在带有win7的Logitech键盘上,箭头键码为37,38,39和40,其中repr为',返回为13,带有repr'\\ r'。 这些键码与您显示的内容或此页面的声明不匹配。

但是,同一页面建议使用event.keysym或event.keysym_num。 它没有指出的是,非私人字符键的数字,如Shift,Up,F1等,在“私人使用区域”中仅低于2 ** 16(65536)。 ascii字符的数字是它们的ascii代码,等于它们的unicode序数。 我怀疑所有BMP unicode字符的数字是它们的unicode序数(tk只编码BMP)。

我能看到的关键码的唯一用途是告诉数字键盘键和其他地方的相同键之间的区别。

您的方法存在的问题是,几乎不可能计算您寻求的信息。 通过查询窗口小部件属性和/或数据,您可以获得所需的所有信息,因此尝试自己跟踪行和列是没有意义的。

这个例子不是一个优雅的解决方案,所以我认为根据操作系统“硬编码”键码更好。

# 1. Generate keystrokes using Python + Tkinter.
# 2. Save needed keycodes in the dictionary.
# 3. Use dictionary with keycodes to handle keystrokes independently from
#    operating system, language or (maybe?) keyboard model.
# This is not an elegant solution, so I think it is better to "hardcode"
# keycodes depending on the operating system.
import tkinter as tk

def keystroke(event):
    dict[event.keycode] = event.keysym  # save keycodes into the dictionary

def keyboardevent(str):
    # Code that simulated 'key' being pressed on keyboard
    temp.after(10, lambda: temp.event_generate('<Key-{}>'.format(str)))

temp = tk.Tk()
temp.withdraw()  # remove the window from the screen (without destroying it)
temp.bind('<Key>', keystroke)
dict = {}  # dictionary of the needed keycodes
keyboardevent('w')  # generate needed keyboard events
keyboardevent('s')
keyboardevent('a')
keyboardevent('d')
temp.after(20, temp.destroy)  # this is not needed anymore
temp.mainloop()

# Start your code here
def keys_handler(event):
    if event.keycode in dict:
        print(dict[event.keycode])

root = tk.Tk()
root.focus_force()
root.bind('<Key>', keys_handler)
root.mainloop()

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM