【发布时间】:2020-05-30 23:00:49
【问题描述】:
在 Windows 10 上的 Python 3.x 上运行
我正在编写一个脚本来帮助将 .tiff 图像序列自动编译成视频。我正在使用 wxPython 来构建 GUI。首先我创建窗口类并为窗口设置一个全局变量。
global main_window
main_window = self
然后我有一个函数用于写入状态栏并将值打印到控制台(有时我还添加代码以从我发送到此函数的文本中写入日志文件)。
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)
这是我写的moviePy函数,用来将图像序列转换成ta视频。
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))
打印到控制台确实显示了进度,但是状态栏没有填充当前进程的进度。因为我希望最终将此作为 .pyw 运行,其中状态栏显示进度,对我来说,让进度条显示在状态栏中很重要,但是我很难找到一种方法来做到这一点.
更新(2020 年 6 月 1 日):
我已经设法使用 2 个函数来启动和停止进度条,并使用 2 个面板而不是一个面板创建状态栏。
我在 MainWindow 类中的状态栏代码已更改为:
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)
我的启动动画的函数:
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
还有我停止动画的功能:
def stop_busy_statusbar(window):
window.progress_bar.Destroy()
window.progress_bar = wx.Gauge(window.statusbar, -1, size=(280, 25), style=wx.GA_PROGRESS)
感觉有点粗糙,但确实有效。
所以调用 video_from_sequence() 函数的 convert() 函数如下所示:
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)
我现在遇到的是,窗口在处理图像序列时被锁定。有人建议我使用单独的线程或使用 wx.Yield。我不太确定如何执行这些事情。我试过 CallAfter(function(vars)) 但这似乎不起作用。
我复制了代码 sn-ps 来演示它在 wxPython 中的工作原理,但我并不真正理解它是如何工作的,也无法让它在我的脚本中工作。
【问题讨论】:
标签: python python-3.x wxpython moviepy