【问题标题】:Python 2.7: Detect DELETE key pressed on raw_inputPython 2.7:检测在 raw_input 上按下的 DELETE 键
【发布时间】:2013-08-16 15:55:21
【问题描述】:

我正在准备一个非常简单的脚本,我需要用户输入某些值。在某个时刻,如果用户输入是 DELETE 键(用户按 DELETE 然后 Enter),我想提供重用现有值或删除它的机会,但我似乎无法找到令人满意的答案(我觉得这很令人惊讶...)它只是一个辅助脚本,所以我试图避免使用更高级的东西,例如 PyHook 和类似的东西。

这是我感兴趣的块:

if reusable_params:
    for key in list(k for k in config_dict.keys() if k not in ["mac", "base_url", "command_name"]):
        msg = "Enter new value for parameter {0}. Press ENTER to reuse the previous {1}. Press DELETE+ENTER to remove this key.".format(key, config_dict[key])
        input = unicode(raw_input(msg).strip().decode(sys.stdin.encoding))
        logging.debug("input: %s, len(input) %s" % (input, len(input))

按 DELETE+Enter 会返回一个 unicode 的 4 个字符的字符串:

提前谢谢你!

【问题讨论】:

  • raw_input 无法捕获单个击键(显然 Enter 键除外)。如果你真的想保持你的脚本简单,你最好的选择是放弃这个功能,转而使用一个更易于处理的功能(即按 Enter 而不输入任何输入以显示以前输入的命令列表,再次按 Enter 执行最后一条命令)

标签: python input console-application special-characters


【解决方案1】:

你可能想看看pykeylogger,它允许你捕捉键盘事件,另一个选择是使用pygame,它有很好的按键事件支持。

对于pygame

具体来说,你可能想看看这个page (pygame.keys),

K_DELETE              delete #thanks to @7stud

所以你可能可以做这样的事情,

key = pygame.key.get_pressed()
        if key[pygame.K_DELETE]:
           #your code here...

对于pykeylogger,来自here

import keylogger
import time

now = time.time()
done = lambda: time.time() > now + 60
def print_keys(t, modifiers, keys): print "%.2f   %r   %r" % (t, keys, modifiers)

keylogger.log(done, print_keys)

【讨论】:

  • 退格(ascii 代码 8)不等同于 delete(ascii 代码 127)。如果您再往下看它显示的列表:K_DELETE
  • @7stud 谢谢!我没有意识到这一点。
【解决方案2】:

您的 cmd 窗口是一个软件,即一个计算机程序。当您在 cmd 窗口中按下 delete 键时,cmd 窗口会被编程,因此它不会将 delete 键 (127) 的 ascii 代码添加到存储到目前为止输入的所有击键的数组中,即输入缓冲区。相反,当您按下删除键时,cmd 窗口会被编程为从数组中删除最后一次击键。很简单:

key_strokes = []

#get key_code

if key_code == 127:
    key_strokes.pop()
else:
    key_strokes.append(key_code)

问题是你需要控制产生 cmd 窗口的程序来改变它的行为方式。

最简单的解决方案是让您的用户输入“d”进行删除,而不是按删除键。

否则,您需要在用户键入时捕获击键。响应击键(而不是等待 Enter 键)的最佳和最有效的方法是了解 Tkinter。您可以向您的用户展示您创建的窗口——所谓的 GUI,并且您可以对其进行编程以在用户按下删除键时执行任何您想做的事情:

import Tkinter as tk

root = tk.Tk()
root.geometry("300x200")

entry = tk.Entry(root)
entry.pack()

def get_key(event):
    print "You pressed", repr(event.char)
entry.bind("<Key>", get_key)

root.mainloop()

做类似事情的另一种方法是使用 curses 模块,这是对时间的巨大浪费。你花在整理诅咒上的时间最好花在学习 Tkinter 上。

现在,您的代码中发生了什么:

list(k for k in config_dict.keys() if k not in ["mac", "base_url", "command_name"]):

为什么要创建一个生成器,然后在从生成器中提取列表后立即将其丢弃?消除生成器步骤有什么问题:

[
    k for k in config_dict.keys() 
    if k not in ["mac", "base_url", "command_name"]
]

如果你对“nots”使用集合而不是列表,效率会更高。必须搜索整个列表并不像一个字典查找那样有效:

[
    k for k in config_dict.keys() 
    if k not in set(["mac", "base_url", "command_name"])
]

【讨论】:

    猜你喜欢
    • 2012-09-03
    • 2020-11-16
    • 1970-01-01
    • 1970-01-01
    • 2018-12-03
    • 2018-12-09
    • 1970-01-01
    • 1970-01-01
    • 2018-10-02
    相关资源
    最近更新 更多