Let's say I have a python script which reads all the images in a folder and resizes them. The script works all by his own, it takes in two arguments - the input folder and an output folder. To have a visual response of the progress I'm using a progressbar which is printed out to the console/terminal.
resize.py:
import argparse
import fnmatch
import os
import PIL
from PIL import Image
from progress.bar import Bar
parser = argparse.ArgumentParser(description='Photo resizer.')
parser.add_argument('input_folder', nargs='?', default='', help="Input folder")
parser.add_argument('export_folder', nargs='?', default='', help="Output folder")
args = parser.parse_args()
if args.input_folder:
input_folder = args.input_folder
if args.export_folder:
export_resized_folder = args.export_folder
NEW_SIZE = 2000
inputFiles = []
for root, dirnames, filenames in os.walk(input_folder):
for filename in fnmatch.filter(filenames, '*.jpg'):
inputFiles.append(os.path.join(root, filename))
bar = Bar("Processing photos", max=len(inputFiles), check_tty=False)
for photo in inputFiles:
filename = os.path.basename(photo)
im = Image.open(photo)
im_width, im_height = im.size
if im_width > im_height:
new_width = NEW_SIZE
new_height = int(NEW_SIZE * im_height / im_width)
else:
new_height = NEW_SIZE
new_width = int(NEW_SIZE * im_width / im_height)
new_size = (new_width, new_height)
im_resized = im.resize(new_size, resample=PIL.Image.Resampling.LANCZOS)
im_resized.save(os.path.join(export_resized_folder, filename), quality=70)
bar.next()
bar.finish()
Now I have an another script (main_gui.py) which does some batch processing and one of the jobs is to resize the images. This script provides a simple GUI. When it comes to resizing the images, I use subprocess Popen to execute the script and pass in the input and output folders as args.
So in main_gui.py I start the subprocess:
script_path = "resize.py"
process = subprocess.Popen(["python", script_path, INPUT_FOLDER, OUTPUT_FOLDER], universal_newlines=True, stdout=subprocess.PIPE)
Now I'd like to see the progress in the GUI also. I don't know if I'm doing it correctly (It is a high probability that not, this is just the first thing that came to my mind)...
So in resize.py along with the progressbar I print out information about my progress and then read it in the main_gui.py and based on that information I update a tkinter progressbar.
In resize.py:
bar = Bar("Processing photos", max=len(inputFiles), check_tty=False)
print("**TOTAL** " + str(len(inputFiles)))
...
progressCounter = 1
for photo in inputFiles:
...
bar.next()
print("**PROGRESS** " + str(progressCounter))
progressCounter += 1
...
I read these values in main_gui.py
process = subprocess.Popen(["python", script_path], universal_newlines=True, stdout=subprocess.PIPE)
while process.poll() is None:
data = process.stdout.readline().strip()
print(data)
if "**TOTAL** " in data:
total = int(data.replace("**TOTAL** ", ""))
progressbarWidget['maximum'] = total
if "**PROGRESS** " in data and self.GUI:
progressCounter = int(data.replace("**PROGRESS** ", ""))
progressbarWidget['value'] = progressCounter
progressbarWidget.update_idletasks()
And at this point I'd like in my resize.py check if it is run by itself or by the subprocess, so I don't have the unnecessary print statements.
I tried pass in an env value as Charles suggested in the comments, but couldn't get it done
PPIDis for.