如何将子进程脚本输出到 GUI?

Posted

技术标签:

【中文标题】如何将子进程脚本输出到 GUI?【英文标题】:How can I output subprocess script to GUI? 【发布时间】:2019-08-15 09:22:08 【问题描述】:

我正在努力将输出从另一个 GUI 中转换为 GUI。 我知道有类似的帖子,但在不知情的情况下,我无法对我的问题做出正面或反面。

我有一个脚本使用 os.system 从 mdadm --details 中调用有关我的 RAID 阵列的信息。我还有一个用于带有子进程的 GUI 的小而简单的脚本,因此按钮将调用该脚本。但我无法让它将代码输出到另一个 GUI 窗口。

这是我的 os.system 脚本。

import os
os.system("sudo mdadm -D /dev/md0 | grep -A 3 State && grep -A 3 RaidDevice")

另一个脚本是我的简单 GUI,我无法调整以获得我想要的结果。

from tkinter import *
from tkinter import messagebox
top = Tk()

top.title('RAID Status')
top.geometry("250x160")

def raidStat():
   import subprocess
   subprocess.call(['./raidScripts/mdadmRaid.py'])

button1 = Button(top, text = "Check Status", command = raidStat)
button1.grid(row=1,column=0)

top.mainloop()

os.system 脚本在终端中运行,并在文本编辑器中返回结果。

因为我不知道代码,所以我无法在 GUI 的输出方面做任何其他工作。

【问题讨论】:

好的。所以这将是这样的:导入子进程,然后 subprocess.run 使用相同的命令来获取输出?让它更有可能与 GUI 一起工作,还是仍然需要一些调整? 【参考方案1】:

您的脚本执行此操作的最小更改:

from tkinter import *
from tkinter import messagebox
top = Tk()

top.title('RAID Status')
top.geometry("250x160")

def raidStat():
   import subprocess
   myproc = subprocess.run(['./raidScripts/mdadmRaid.py'], stdout=subprocess.PIPE)
   messagebox.showinfo("Result", myproc.stdout)

button1 = Button(top, text = "Check Status", command = raidStat)
button1.grid(row=1,column=0)

top.mainloop()

请注意,我们现在将stdout 重定向到subprocess.PIPE 并使用创建的进程对象的stdout 属性来访问其内容。从 Python 3.7 开始,您可以使用 capture_output=True 调用 subprocess.run(),而不是使用 stdout(和/或 stderr)。

就像在您的代码中一样,脚本输出并没有被 Python 触及。这就是为什么您可以在控制台上看到它,但无法访问它以在您的 GUI 中显示它的原因。

【讨论】:

我进行了更改,但仍然收到与以前相同的错误消息,我是否缺少某种包或关键信息? Tkinter 回调 Traceback 中的异常(最近一次调用最后一次):文件“/usr/lib/python3.5/tkinter/__init__.py”,第 1562 行,在 call return self.func(*args) File "/home/pi/Desktop/raidScripts/mdadmStatus.py", line 12, in raidStat myproc = subprocess.run(['./raidScripts/mdadmRaid.py'], stdout=subprocess .PIPE) 文件“/usr/lib/python3.5/subprocess.py”,第 383 行,以 Popen(*popenargs, **kwargs) 作为进程运行:文件“/usr/lib/python3.5/subprocess. py",第 676 行,在 init restore_signals, start_new_session) 文件“/usr/lib/python3.5/subprocess.py”,第 1282 行,在 _execute_child 中引发 child_exception_type(errno_num, err_msg) FileNotFoundError:[Errno 2] 没有这样的文件或目录:'。 /raidScripts/mdadmRaid.py' 为多条消息道歉。 在调用subprocess.run()之前尝试添加print(os.getcwd())(当然需要导入os)。请注意,mdadmRaid.pymdadmStatus.py 位于同一目录中,因此os.getcwd() 的结果将是/home/pi/Desktop/raidScripts。因此,建议将./raidScripts/mdadmRaid.py改为mdadmRaid.py 将两个脚本放在一起并不是问题的原因。问题是您使用了错误的路径。您可以使用script_path = os.path.dirname(os.path.abspath(__file__)) 获取主脚本的目录名称,然后使用os.path.join(script_path, 'mdadmRaid.py') 构造mdadmRaid.py 的完整路径。

以上是关于如何将子进程脚本输出到 GUI?的主要内容,如果未能解决你的问题,请参考以下文章

如何通过管道将子进程调用传递给文本文件?

如何获取子进程的输出

无法将子进程发送回父进程的消息

将子进程的 stdout 和 stderr 重定向到两个命名管道(然后从它们读回)

如何隐藏子进程的输出并继续执行脚本?

C++ fork 进程但不是子进程