#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')
.