关闭终端后,终端中写入的输入将被复制到我的代码中。为什么?

问题描述 投票:0回答:1

我本质上正在制作一个自定义 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 函数会很有帮助。

python visual-studio-code listener pynput tui
1个回答
0
投票

为了防止脚本结束后键盘输入传递到系统,需要设置参数

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 文档有关此问题的常见问题解答可以在此处找到

© www.soinside.com 2019 - 2024. All rights reserved.