如何在python 3中使用线程从键盘输入?

时间:2012-12-26 16:41:38

标签: python multithreading python-3.x

我正在制作一个蛇游戏,要求玩家按下WASD键而不停止游戏过程以获得玩家的输入。所以我不能使用input()来解决这种情况,因为游戏会停止滴答作响。

我找到了一个getch()函数,它可以在不按Enter的情况下立即给出输入,但是这个函数也会停止游戏滴答以获得像input()这样的输入。我决定使用线程模块通过getch()在不同的线程中获取输入。问题是getch()在不同的线程中没有工作,我不知道为什么。

import threading, time
from msvcrt import getch

key = "lol" #it never changes because getch() in thread1 is useless

def thread1():
    while True:
        key = getch() #this simply is almost ignored by interpreter, the only thing it
        #gives is that delays print() unless you press any key
        print("this is thread1()")

threading.Thread(target = thread1).start()

while True:
    time.sleep(1)
    print(key)

那么为什么getch()thread1()时无效?

2 个答案:

答案 0 :(得分:5)

问题是您在key内创建了一个局部变量thread1,而不是覆盖现有变量。快速简便的解决方案是将key声明为thread1内的全局。

最后,你应该考虑使用锁。我不知道是否有必要,但我想如果你在同时打印出来的时候尝试在线程中向key写一个值,就会发生奇怪的事情。

工作代码:

import threading, time
from msvcrt import getch

key = "lol"

def thread1():
    global key
    lock = threading.Lock()
    while True:
        with lock:
            key = getch()

threading.Thread(target = thread1).start()

while True:
    time.sleep(1)
    print(key)

答案 1 :(得分:0)

我尝试使用getch,但它对我不起作用......(win7在这里)。

您可以尝试使用tkinter模块//但我仍然无法使其与线程一起运行

# Respond to a key without the need to press enter
import tkinter as tk    #on python 2.x use "import Tkinter as tk"

def keypress(event):
    if event.keysym == 'Escape':
        root.destroy()
    x = event.char
    if x == "w":
        print ("W pressed")
    elif x == "a":
        print ("A pressed")
    elif x == "s":
        print ("S pressed")
    elif x == "d":
        print ("D pressed")
    else:
        print (x)

root = tk.Tk()
print ("Press a key (Escape key to exit):")
root.bind_all('<Key>', keypress)
# don't show the tk window
root.withdraw()
root.mainloop()

正如Michael0x2a所说,你可以尝试使用制作游戏的库 - pygame或pyglet。

@EDIT @ Michael0x2a: 你确定你的代码有效吗? 无论我按什么,它总是打印相同的键。

@ EDIT2: 谢谢!