使用Pygame的Python subprocess.Popen(),如何告诉Pygame等到子进程完成

时间:2015-01-03 20:34:19

标签: python pygame subprocess python-3.4

我有一个太多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文件,然后处理您的代码。

1 个答案:

答案 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()来避免这种情况。