Как я могу вывести скрипт подпроцесса в GUI?

#python #user-interface #tkinter #subprocess #output

#python #пользовательский интерфейс #tkinter #подпроцесс #вывод

Вопрос:

Я борюсь с преобразованием выходных данных в графический интерфейс из другого графического интерфейса. Я знаю, что есть похожие сообщения, но без знаний я не могу разобраться в них с моей проблемой.

У меня есть скрипт, использующий os.system для вызова информации из mdadm — сведений о моем RAID-массиве. У меня также есть небольшой упрощенный скрипт для GUI с подпроцессом, чтобы кнопка вызывала скрипт. Но я не могу заставить его выводить код в другое окно графического интерфейса.

Это мой скрипт для os.system.

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

Другой скрипт — это мой простой графический интерфейс, который я не могу настроить для получения желаемых результатов.

 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 работает в терминале и возвращает результаты в текстовом редакторе.

Я не могу заставить что-либо еще работать с точки зрения вывода для графического интерфейса, потому что я не знаю кода.

Комментарии:

1. ОК. Итак, это было бы что-то вроде: импортировать подпроцесс, затем subprocess.run с той же командой, которая должна захватить выходные данные? Повысить вероятность его работы с графическим интерфейсом или все равно потребуется некоторая настройка?

Ответ №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, вы можете просто вызывать subprocess.run() with capture_output=True вместо того, чтобы иметь дело с stdout (и / или stderr ).

Как и в вашем коде, вывод скрипта не был затронут, и все это Python. Это причина, по которой вы могли видеть его на консоли, но не могли получить к нему доступ, чтобы отобразить в вашем графическом интерфейсе.

Комментарии:

1. Я внес изменения, но я по-прежнему получаю те же сообщения об ошибках, что и раньше, я пропускаю какой-то пакет или ключевой бит информации?

2. Исключение в трассировке обратного вызова Tkinter (последний последний вызов): Файл «/usr/lib/python3.5/tkinter/__init__.py «, строка 1562, в файле call return self.func(* args) «/home/pi/Desktop/raidScripts/mdadmStatus.py «, строка 12, в raidStat myproc = subprocess.run([‘./raidScripts/mdadmRaid.py ‘], стандартный вывод=подпроцесс. Файл PIPE) «/usr/lib/python3.5/subprocess.py «, строка 383, при запуске с Popen (*popenargs, **kwargs) как process: File «/usr/lib/python3.5/subprocess.py «, строка 676, в инициализации restore_signals, start_new_session)

3. Файл «/usr/lib/python3.5/subprocess.py «, строка 1282, в _execute_child вызываем child_exception_type(errno_num, err_msg) Ошибка FileNotFoundError: [Ошибка 2] Нет такого файла или каталога: ‘./raidScripts/mdadmRaid.py Приносим извинения за многочисленные сообщения.

4. Попробуйте добавить print(os.getcwd()) (конечно, вам нужно импортировать os ) перед вызовом subprocess.run() . Обратите внимание, что mdadmRaid.py он находится в том же каталоге mdadmStatus.py , что и os.getcwd() , поэтому результатом /home/pi/Desktop/raidScripts было бы, ,,. Поэтому предлагаю изменить ./raidScripts/mdadmRaid.py на mdadmRaid.py .

5. Объединение двух скриптов не является причиной вашей проблемы. Проблема в том, что вы используете неправильный путь. Вы можете получить имя каталога вашего основного скрипта с помощью script_path = os.path.dirname(os.path.abspath(__file__)) , а затем построить полный путь к mdadmRaid.py использованию os.path.join(script_path, 'mdadmRaid.py') .