Home > Enterprise >  Realtime subprocess output in Tkinter GUI
Realtime subprocess output in Tkinter GUI

Time:12-21

I want to view latest output from my subprocess exe file in my Tkinter GUI. Label or textbox, anything. I've been trying to find the solution and it seemed some of the questions could be helpful, but unfortunately, not so much.

This is the function that reads the exe file. It prints it but not in tkinter window.

root = tkinter.Tk()
root.geometry('1368x780')


def function:
    with Popen('/Users/User/Desktop/mcm/mcm/test', stdout=PIPE, bufsize=1, universal_newlines=True) as p:
        for line in p.stdout:
            print(line, end='')  # process line here
            percent=tkinter.Label(root, text=(line))
            percent.place(x=1285, y=230)


        if p.returncode != 0:
            raise CalledProcessError(p.returncode, p.args)
            label=tkinter.Label(root,text='✔', fg='green')
            label.place(x=1285, y=250)

The output from file is just basically percents: 0.1% 0.2%

CodePudding user response:

I've had some luck handling a similar issue with the following method

label_var = tkinter.StringVar(root, '')  # declare a StringVar to store STDOUT info
# create the label and bind it to the 'label_var' so it updates when 'label_var' changes
pct_label = tkinter.Label(root, textvariable=label_var)
pct_label.place(x=1285, y=230)  # the label is blank '' by default, so you won't see it


def function():  # you really should name this something more descriptive...
    CREATE_NO_WINDOW = 0x0800_0000  # this flag hides the shell window
    proc_config = {  # kwargs for your subprocess call
        'buffsize': 1,  # how many lines to output at once
        'creationflags': CREATE_NO_WINDOW,
        'shell': False,
        'stdout': PIPE,
        'text': True,
    }
    with Popen('/Users/User/Desktop/mcm/mcm/test', **proc_config) as proc:
        while proc.poll() is None:  # update the label as long as the process is running
            if value := proc.stdout.readline().strip():  # get value, strip whitespace
                label_var.set(value)  # update the label variable (and the label)
                root.update_idletasks()  # refresh GUI (you might not need this)
  • Related