Python subprocess.Popen() with Pygame , how to tel

2019-09-06 09:33发布

问题:

I have a major issue that too many Pygame users has, I want to take input from user in Pygame. I probably check all informations in internet,include stackoverflow, nothing solved.

So I decide to make a solution, I created another Python script(I convert it to .exe so subprocess can open it) that asking question to user before Pygame is running, after then that script saving user's data into a .txt file(like a database).Then in Pygame I opening that .txt file and taking the data. Therocially it's working, but problem is, I have to tell Pygame, while subprocess is processing, wait for it. That's how I can dodge errors like IndexError etc. Because I'm using readlines() and untill that .exe file is closed, Pygame has to wait, if not; readlines() giving data as list and it throwing IndexError normally. So Pygame has to wait untill I put the data in that .exe file. Let me explain with my codes;

This is the script that taking data from user(I converted it to exe already so subprocess can open):

#!/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

And then, in Pygame, I'am opening this .exe file, but Pygame won't wait and normally I'm getting error.

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))

This method is almost working, I thought finally I got the solution of this input problem in Pygame.But I don't know how to tell Pygame, wait untill I'm done with .exe file, then process your codes.

回答1:

Use the communicate method:

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.

So this is the code to do it:

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

Edit:

As @Padraic suggests, you can use check_call, which is more informative when failing:

try:
    subprocess.check_call([’wtf.exe’])
except subprocess.CalledProcessError:
    pass # handle errors in the called executable
except OSError:
    pass # executable not found

Another option is call:

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

So something like this:

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

And you can also use wait if you don't care about the data and just want the return code to see if something bad happened. But documentation says you should prefer 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.