【问题标题】:Python subprocess.Popen() with Pygame , how to tell Pygame wait untill subprocess is donePython subprocess.Popen() 与 Pygame ,如何告诉 Pygame 等到子进程完成
【发布时间】:2015-03-01 19:03:23
【问题描述】:

我有一个主要问题是 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文件,然后处理您的代码。

【问题讨论】:

  • 您可以改用os.system("wtf.exe")
  • 您无需将 Python 脚本转换为 exe,即可​​将其作为子进程运行([sys.executable, '/path/to/script'] 作为命令即可)。您不需要将 Python 脚本作为子进程运行,以便在不阻塞 pygame 事件循环的情况下执行一些 Python 代码(您可以改用 threadingmultiprocessingconcurrent.futuresasyncio 模块)。您不应使用 input() 在 GUI 应用程序中获取用户输入,例如,请参阅 code near evt.unicode.isalpha() 了解一种可能的替代方法。

标签: python pygame subprocess python-3.4


【解决方案1】:

使用communicate 方法:

与进程交互:将数据发送到标准输入。从 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 管道缓冲区接受更多数据。使用communicate() 来避免这种情况。

【讨论】:

  • 它解决了。我真的想了解这个 communicate() 是如何工作的? 输出,错误 ?请您再解释一下,让我检查一下是否正确。
  • check_call 可能是更好的选择。
  • @PadraicCunningham 它们有什么区别,能告诉我吗?
  • @PadraicCunningham 为什么它比call 更受青睐?反正我大部分时间都用communicate...
  • @grrr 我从文档中为每个方法添加了信息,每个函数的名称都是文档的实际链接。
猜你喜欢
  • 2013-12-25
  • 1970-01-01
  • 2020-09-10
  • 2015-04-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多