1

I wanted to try out some GUI stuff in Python. Im new to both Python and PySimpleGUI. I decided to make a program that when given an IP address would ping it and show the reply in a popup. (super simple i know.)

It works perfectly, however: It is showing the response in the console, but I want it in the GUI.

Is it possible to save the console output in a variable and that way show it in the GUI?

I hope the question makes sense :)

This is my code:

#1 Import:
import PySimpleGUI as sg
import os

#2 Layout:
layout = [[sg.Text('Write the IP-address you want to ping:')],
          [sg.Input(key='-INPUT-')],
          [sg.Button('OK', bind_return_key=True), sg.Button('Cancel')]]
#3 Window:
window = sg.Window('Windows title', layout)

#4 Event loop:
while True:
    event, values = window.read()
    os.system('ping -n 1 {}'.format(values['-INPUT-']))
    if event in (None, 'Cancel'):
        break
        
#5 Close the window:
window.close()
houndedfella
  • 11
  • 1
  • 1
  • 4
  • The Demo Programs on the PySimpleGUI GitHub has several programs that show you exactly how to do this. Demo_Script_Launcher_Realtime_Output.py will launch a program using Popen and then display the output in realtime in your window. The Demoi Programs are an excellent resource for questions like this. – Mike from PSG Nov 04 '20 at 21:21
  • Thanks @MikeyB - will check it out! – houndedfella Nov 05 '20 at 16:33

1 Answers1

3

Hi found the answer here : https://stackoverflow.com/a/57228060/4954813

I have been testing it with python 3.9 works like a charm ;-)

import subprocess
import sys
import PySimpleGUI as sg

def main():
    layout = [  [sg.Text('Enter a command to execute (e.g. dir or ls)')],
            [sg.Input(key='_IN_')],             # input field where you'll type command
            [sg.Output(size=(60,15))],          # an output area where all print output will go
            [sg.Button('Run'), sg.Button('Exit')] ]     # a couple of buttons

    window = sg.Window('Realtime Shell Command Output', layout)
    while True:             # Event Loop
        event, values = window.Read()
        if event in (None, 'Exit'):         # checks if user wants to 
            exit
            break

        if event == 'Run':                  # the two lines of code needed to get button and run command
            runCommand(cmd=values['_IN_'], window=window)

    window.Close()

# This function does the actual "running" of the command.  Also watches for any output. If found output is printed
def runCommand(cmd, timeout=None, window=None):
    p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
    output = ''
    for line in p.stdout:
        line = line.decode(errors='replace' if (sys.version_info) < (3, 5) else 'backslashreplace').rstrip()
        output += line
        print(line)
        window.Refresh() if window else None        # yes, a 1-line if, so shoot me
    retval = p.wait(timeout)
    return (retval, output)                         # also return the output just for fun

if __name__ == '__main__':
    main()
  • I had to add "from sys import exit" – XYZ Jan 04 '23 at 02:57
  • this has limitation. If I have a command line program that prints progress in one line, I only get the results after run is completed. for example running `gdal_translate` it prints progress `0...10...20...30...40...50...60...70...80...90...100 - done.` I only get the result at the end and this can take even a few hours depending on the size of the operation – mWindows Feb 28 '23 at 13:31