我本质上正在制作一个自定义 TUI,它工作得很好,除了由于某种原因,VSCode 从终端捕获击键并将它们写入我的 python 文件中。简而言之,它甚至从我的系统终端捕获击键,并且不知道如何让它停止。我猜测我以某种方式让侦听器保持打开状态,但我不确定,因为这是我第一次使用 pynput 模块或授予我的 VSCode 系统范围权限。
import math
from pynput import keyboard
from IPython.display import clear_output
open_field = " _ "
wall = " X "
'''
The function, "coordinate_field" creates a grid like the one below, and also prints the location and movement of characters within the grid as the code runs. In future iterations, I intend to make the walls impassable, add momentum and battle functionality.
X X X X X X X X X X X X
X _ _ _ _ _ _ _ _ _ _ X
X _ _ _ _ _ _ _ _ _ _ X
X _ _ _ _ _ _ _ _ _ _ X
X _ _ _ _ _ _ _ _ _ _ X
X _ _ _ _ _ _ _ _ _ _ X
X _ _ _ _ _ _ _ _ _ _ X
X _ _ _ _ _ _ _ _ _ _ X
X _ _ _ _ _ _ _ _ _ _ X
X _ _ _ _ _ _ _ _ _ _ X
X _ _ _ _ _ _ _ _ _ _ X
X X X X X X X X X X X X
'''
def coordinate_field (p1_location, p2_location, p1_direction, p2_direction):
x_coordinate = 0
y_coordinate = 1
field = ""
'''
The grid is 12*12.
156 is 12*12+12 because adding each line break takes an
iteration as well.
'''
for i in range(156):
x_coordinate += 1
coordinate_point = [x_coordinate, y_coordinate]
if x_coordinate > 12:
field += "\n"
x_coordinate -= 13
y_coordinate += 1
elif y_coordinate in [1,12] or x_coordinate in [1,12]:
field += wall
# The following elifs add the characters.
elif coordinate_point == p1_location:
field += p1_direction
elif coordinate_point == p2_location:
field += p2_direction
else:
field += open_field
clear_output(wait=True)
print(field)
p1_location = [4, 7]
'''
This following list will be joined before going in to the function. I think that it needs to be a list at this stage
because p1_direction += "<" and such didn't seem to work in this context.
'''
p1_direction = ["-","-","-"]
'''
on_press is probably the source of the issue, unless the
keyboard.Listener is. I don't really understand either, and got
both from ChatGPT.
'''
def on_press(key):
try:
if key == keyboard.Key.enter:
return False # Stop listener
elif key == keyboard.Key.left:
p1_direction.append("<")
elif key == keyboard.Key.right:
p1_direction.append(">")
elif key == keyboard.Key.up:
p1_direction.append("^")
elif key == keyboard.Key.down:
p1_direction.append("v")
except AttributeError:
pass
def movement (p1_direction):
print ("Type three moves: ")
with keyboard.Listener(on_press=on_press) as listener:
listener.join()
# This loop guarantees that only the last three directional
# inputs are counted.
while len(p1_direction) > 3:
p1_direction.remove(p1_direction[0])
# This translates the inputs into motion.
for i in range(len(p1_direction)):
if p1_direction[i] == "^":
p1_location[1] -= 1
if p1_direction[i] == "v":
p1_location[1] += 1
if p1_direction[i] == "<":
p1_location[0] -= 1
if p1_direction[i] == ">":
p1_location[0] += 1
# Finally, the list is joined, used as an argument in the
# coordinate_field function, and separated again.
p1_direction = "".join(p1_direction)
coordinate_field (p1_location, [7,5], p1_direction, "^^<")
p1_direction = list(p1_direction)
return p1_direction
# All this code will someday be part of a larger game, but for
# now, I run it endlessly to test it.
while True:
p1_direction = movement(p1_direction)
随着代码运行,您输入的任何随机字符都会写入我的 python 代码中。我想要的只是让角色在场地中移动,而且我还有很多功能需要添加。也许知道我从 chatGPT 获得了 on_press 函数会很有帮助。
为了防止脚本结束后键盘输入传递到系统,需要设置参数
suppress=True
with keyboard.Listener(on_press=on_press) as listener:
listener.join()
我在这篇未答复的帖子中找到了相关提示。
这里是pynput中参数的相关文档:
suppress (bool) – 是否抑制事件。将其设置为 True 将阻止输入事件传递到系统的其余部分。
但请注意,这意味着在脚本运行时,任何其他应用程序中的击键都将被忽略,包括用于结束脚本的 Ctrl+C KeyboardInterupt 命令。您可以使用
on_release
回调函数添加另一种退出脚本的方法,例如:
stop = False
def on_release(key):
global stop
# If user hits Esc, end the program
if key == keyboard.Key.esc:
stop = True
return False
...
#In the main loop:
if stop:
sys.exit()
如果您只想禁止某些事件进入系统,那么您需要将系统特定的回调函数传递给正确的命名参数。 pynput 文档有关此问题的常见问题解答可以在此处找到