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

Python subprocess.Popen() with Pygame , how to tell Pygame wait untill subprocess is done

我有太多 Pygame 用户遇到的主要问题,我想听取 Pygame 中用户的意见。我大概查了网上所有的资料,包括Whosebug,都没有解决。

所以我决定制定一个解决方案,我创建了另一个 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.But中找到了这个输入问题的解决方案我不知道怎么说Pygame, 等我处理完 .exe 文件,然后处理你的代码。

使用communicate方法:

Interact with process: Send data to stdin. Read data from stdout and stderr, until end-of-file is reached. Wait for process to terminate. The optional input argument should be a string to be sent to the child process, or None, if no data should be sent to the child.

所以这是执行此操作的代码:

process = subprocess.Popen(["wtf.exe"])
# block until process done
output, errors = process.communicate()

编辑:

正如@Padraic 所建议的,您可以在失败时使用 check_call, which is 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:

Run the command described by args. Wait for command to complete, then return the returncode attribute.

所以像这样:

returncode = subprocess.call(["wtf.exe"])

如果您不关心数据而只想使用 return 代码查看是否发生了不好的事情,您也可以使用 wait。但是文档说你应该更喜欢 communicate:

Warning: This will deadlock when using stdout=PIPE and/or stderr=PIPE and the child process generates enough output to a pipe such that it blocks waiting for the OS pipe buffer to accept more data. Use communicate() to avoid that.