0

This is the current UI script I have written...

import tkinter as ttk
import subprocess
import sys
import time
import os
import tkinter.font as font
from tkinter.ttk import *

app = ttk.Tk()

app.geometry("400x400")
app.configure(bg='gray')

photo = ttk.PhotoImage(file=r"C:\Users\ex\ex_button_active.png")
myFont = font.Font(family='Helvetica', size=20, weight='normal')

ttk.Label(app, text='Ex', bg='gray', font=(
    'Verdana', 15)).pack(side=ttk.TOP, pady=10)
app.iconbitmap(r'C:\Users\ex\ex_icon.ico')


def ex_activation():
    global pro
    print("Running program!")
    pro = subprocess.Popen("python programex.py", shell=True)


def ex_stop():
    global pro
    print("Stopping Program... Please Wait!")
    os.kill(pro.pid, 0)


ex_activation_button = ttk.Button(app, bg='black', image=photo, width=120, height=120, command=ex_activation)

ex_stop_button = ttk.Button(app, bg='Gray', text='Stop Program', width=12, command=ex_stop, height=3)

ex_stop_button['font'] = myFont

app.title("Ex")
ex_activation_button.pack(side=ttk.TOP)
ex_stop_button.pack(side=ttk.LEFT)

# app.mainloop()
while True:
    try:
        app.update()
        app.update_idletasks()
    except KeyboardInterrupt:
        pass

The main goal is to take ANY print statements from the external script and have them printed to a tkinter widget line by line. I wanted to use the stdout method. Here is a post I Had Found that May Help Thank you in advance to anyone that can help me achieve this goal.

Redgar Pro
  • 51
  • 7

1 Answers1

0

You could use a ttk.Label() to show the last printed line on your GUI. You could try this:

# Insert a label on your window
lab = ttk.Label(root, text="Some text")
lab.pack()

# Change the label text
def update_label(print_output):
    lab.configure(text=print_output)

If you prefer having all the lines, you could use a textarea instead of a Label and append the lines instead of replace them.

To get the program output you could do it in multiple ways:

  • Overload the python print() function, and add a line to call update_label(text). See more here, but it's a little bit tricky.
  • Replace all print() to your_print() so you can add the line above in a separate function, like this:
# You will need to make sure to only give one argument, and it should be a string.
def your_print(text):
    update_label(text)
    print(text)
  • The last one will come useful if you can't modify the other program, let's say it's already compiled. You could run the output of that program into a file (SomeCommand > SomeFile.txt), and then every second or so, your tkinter app could call update_label(). An example:
## REPLACE root.mainloop() for this:

# These three lines are the equivalent of mainloop()
while True:
    root.update()
    root.update_idletasks()

    with open('somefile.txt') as filein:
        last_line = filein.read().split('\n')[-1]
        update_label(last_line)
Eric Roy
  • 334
  • 5
  • 15
  • Hi Eric Roy, I like the last of method of creating a text file as the file in for the program. Correct me if I'm wrong but in this answer, I could create a ttk label using the method above and then update that ttk label using a text file as a file in. Did i say this correctly? – Redgar Pro Aug 23 '20 at 00:02
  • Yes, this will work. Keep in mind that Labels were made to hold only one line, so if you plan having all of them you could use a textarea. – Eric Roy Aug 23 '20 at 06:34
  • What would a textarea line look like? I would think it would be something like `app.textarea()` or whatever the root was defined as in the beginning... – Redgar Pro Aug 24 '20 at 04:38
  • Here you have a nice example, this will work for you. https://www.python-course.eu/tkinter_text_widget.php – Eric Roy Aug 24 '20 at 13:49