Running on Python 3.x on Windows 10
I'm working on a script to help automate compiling a .tiff image sequence into a video. I'm using wxPython to build the GUI. First I create the window class and set a global variable for the window.
global main_window
main_window = self
Then I have a function I use to write to the statusbar and also print the values to console(occasionally I also add code to write a log file from the text I send to this function).
def update_status_bar(window, text):
status = str(text)
window.statusbar.SetStatusText(status)
print(status)
window.Refresh()
window.Update()
wx.SafeYield(win=None, onlyIfNeeded=False)
This is the moviePy function I wrote to convert the image sequence into ta video.
def video_from_sequence(image_sequence, video, fps):
img = []
update_status_bar(main_window, 'Getting Image Directory')
path = os.path.dirname(os.path.realpath(image_sequence))
print(path)
update_status_bar(main_window, 'Getting List of Image Files')
for root, dirs, files in os.walk(path):
for file in files:
if file.endswith('.tiff'):
img.append(file)
os.chdir(path)
update_status_bar(main_window, 'Creating Video From Image Sequence')
clip = ImageSequenceClip(img, fps=fps)
update_status_bar(main_window, clip.write_videofile(video, fps=fps))
The print to console does show the progress, however the statusbar is not populating with the current progress of the process. Because I'd like to eventually have this run as a .pyw, where the statusbar shows the progress, it's important to me that I have the progressbar show up in the statusbar, however I'm having trouble finding out a way to do this.
UPDATE (06/01/2020):
I've managed to use 2 functions to start and stop the progress bar, and created the status bar with 2 panels instead of one.
My code within the MainWindow class for the status bar has been changed to:
self.statusbar = self.CreateStatusBar(2)
self.progress_bar = wx.Gauge(self.statusbar, -1, size=(280,25), style=wx.GA_PROGRESS)
self.progress_bar_active = False
self.Show()
self.progress_bar.SetRange(50)
self.progress_bar.SetValue(0)
My function to start the animation:
def start_busy_statusbar(window):
window.count = 0
window.proc = subprocess.Popen(['ping', '127.0.0.1', '-i', '0.2'], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
while True:
wx.Yield()
try:
list_data = window.proc.stdout.readline()
wx.Yield()
except:
break
if len(list_data) == 0:
break
window.progress_bar.Pulse()
wx.Yield()
window.count += 1
And my function to stop the animation:
def stop_busy_statusbar(window):
window.progress_bar.Destroy()
window.progress_bar = wx.Gauge(window.statusbar, -1, size=(280, 25), style=wx.GA_PROGRESS)
Which does feel a bit crude, but it works.
So my convert() function that calls the video_from_sequence() function looks like this:
def convert(self, event):
start_busy_statusbar(main_window)
image_sequence = str(self.text_image_sequence_dir.GetValue())
original_video = str(self.text_original_video_dir.GetValue())
if image_sequence.endswith('.tiff') and original_video.endswith('.mkv'):
try:
new_video = str(original_video)[:-4] + '_1080p.mkv'
temp_video = str(original_video)[:-4] + '_temp.mkv'
print(image_sequence)
print(original_video)
print(new_video)
fps = get_frame_rate(original_video)
print(fps)
video_from_sequence(image_sequence, temp_video, fps)
except FileNotFoundError as e:
e = str(e).replace('Errno 2] ', '')
e = e.replace('directory:', 'directory:\n')
warning(e)
update_status_bar(self, 'Finished')
else:
warning('You must enter valid paths for both a tiff sequence and original video.')
stop_busy_statusbar(main_window)
What I'm running into now, is that the Window locks up while it's processing the image sequence. It's been suggested that I use a seperate thread or utilize the wx.Yield. I'm not quite sure how to execute these things. I've tried CallAfter(function(vars)) but that doesn't seem to work.
I've copied code snippets demonstrating how this works in wxPython, but I don't really understand how it works, and can't get it to work in my script.