我有一个太多Pygame用户的主要问题,我想在Pygame中从用户那里获取输入。我可能检查互联网上的所有信息,包括stackoverflow,没有解决。
所以我决定制作一个解决方案,我创建了另一个Python脚本(我将其转换为.exe,因此子进程可以打开它),在Pygame运行之前向用户提问,之后该脚本将用户的数据保存到.txt文件(如数据库)。然后在Pygame中打开.txt文件并获取数据。它正在工作,但问题是,我必须告诉Pygame,而子进程正在处理,等待它。这就是我如何避免像IndexError等错误。因为我正在使用 readlines()并直到.exe文件被关闭,Pygame必须等待,如果没有; readlines()将数据作为 list 提供,并且正常抛出IndexError。所以Pygame必须等待,直到我把数据放在.exe文件中。让我用我的代码解释一下;
这是从用户获取数据的脚本(我已将其转换为exe,因此子进程可以打开):
#!/usr/bin/env python
# -*-coding:utf-8-*-
while True:
user=input("Please enter your name: ")
try:
user_age=int(input("Please enter your age: "))
except ValueError:
print ("Invalid characters for 'age', try again.")
continue
ask_conf=input("Are you confirm these informations?(Y/N): ")
if ask_conf.lower()=="y":
with open("informations.txt","w") as f: #create the file
f.write(user+"\n")
f.write(str(user_age))
break
else:
continue
然后,在Pygame中,我打开了这个.exe文件,但是Pygame不会等待,通常我会收到错误。
pygame.init()
subprocess.Popen(["wtf.exe"]) #the exe file that taking data from user
#and saving it in "informations.txt"
#codes..
....
....
author = pygame.font.SysFont("comicsansms",25)
with open("informations.txt") as f:
rd=f.readlines()
author1 = author.render("{}".format(rd[0][0:-1]),True,blue) #Pygame won't wait
#so getting IndexError here
age = pygame.font.SysFont("comicsansms",25)
age1 = age.render("{}".format(rd[1]),True,blue)
...
...
...
gameDisplay.blit(author1,(680,15))
gameDisplay.blit(age1,(720,40))
这个方法几乎正常工作,我想最后我在Pygame中得到了这个输入问题的解决方案。但是我不知道如何告诉Pygame,等到直到我完成了.exe文件,然后处理您的代码。
答案 0 :(得分:1)
使用communicate方法:
与流程交互:将数据发送到stdin。从stdout和stderr读取数据,直到达到文件结尾。等待进程终止。可选的输入参数应该是要发送到子进程的字符串,如果没有数据应该发送给子进程,则为None。
所以这是代码:
process = subprocess.Popen(["wtf.exe"])
# block until process done
output, errors = process.communicate()
正如@Padraic建议的那样,你可以使用check_call,失败时为more informative:
try:
subprocess.check_call([’wtf.exe’])
except subprocess.CalledProcessError:
pass # handle errors in the called executable
except OSError:
pass # executable not found
另一个选项是call:
运行args描述的命令。等待命令完成,然后返回returncode属性。
这样的事情:
returncode = subprocess.call(["wtf.exe"])
如果您不关心数据并且只想要返回代码以查看是否发生了错误,您也可以使用wait。但文档说你应该更喜欢communicate
:
警告:当使用stdout = PIPE和/或stderr = PIPE时,这将导致死锁,并且子进程会为管道生成足够的输出,以阻止等待OS管道缓冲区接受更多数据。使用communic()来避免这种情况。