##実現したいこと
youtube-dl を利用して動画をダウンロードし、その状況をwx.ProgressDialog
に表示させようとしました。
1秒ごとにファイルのサイズを取得し、それで、wx.ProgressDialog
に表示させようと、wx.Timer
を使おうとしたときにエラーが発生しました。
##エラーメッセージ
Exception in thread Thread-1: Traceback (most recent call last): File "C:\Users[ユーザー]\AppData\Local\Programs\Python\Python39\lib\threading.py", line 950, in _bootstrap_inner self.run() File "C:\Users[ユーザー]\Desktop\asu.py", line 19, in run self._result = self.acallable() File "C:\Users[ユーザー]\Desktop\asu.py", line 55, in doit self.timer.Start(1000) wx._core.wxAssertionError: C++ assertion "wxThread::IsMain()" failed at ....\src\common\timerimpl.cpp(57) in wxTimerImpl::Start(): timer can only be started from the main thread
##ソースコード
python
1import sys 2import wx 3import threading 4import functools 5import time 6import os 7import os.path 8import youtube_dl 9from math import floor, ceil 10 11class SimpleThread(threading.Thread): 12 """呼び出し可能オブジェクト(関数など)を実行するだけのスレッド""" 13 def __init__(self, acallable): 14 self.acallable = acallable 15 self._result = None 16 super(SimpleThread, self).__init__() 17 18 def run(self): 19 self._result = self.acallable() 20 21 def result(self): 22 return self._result 23 24def task_takes_time(acallable): 25 """ 26 関数デコレータ 27 acallable本来の処理は別スレッドで実行しながら、 28 ウィンドウを更新するwx.YieldIfNeededを呼び出し続けるようにする 29 """ 30 @functools.wraps(acallable) 31 def f(): 32 t = SimpleThread(acallable) 33 t.start() 34 while t.is_alive(): 35 wx.YieldIfNeeded() 36 time.sleep(0.01) 37 return t.result() 38 return f 39 40class MyFrame(wx.Frame): 41 def __init__(self): 42 wx.Frame.__init__(self,None,-1,"YouTubeDownloader") 43 44 self.move_title="" 45 self.move_size="" 46 47 self.panel = wx.Panel(self,-1,size=self.GetSize()) 48 self.button = wx.Button(self.panel,-1," ダウンロード ") 49 self.button.Bind(wx.EVT_BUTTON,self.OnButton) 50 def dld(self, event = None): 51 @task_takes_time 52 def doit(): 53 self.timer = wx.Timer(self) 54 self.Bind(wx.EVT_TIMER,self.OnTimer) 55 self.timer.Start(1000) 56 URL = "https://www.youtube.com/watch?v=bM7SZ5SBzyY&list=PLbkWZECLTN1POhTocktPuvNYCBJbHqh4P" 57 try: 58 data = youtube_dl.YoutubeDL({'outtmpl': '%(title)s.%(ext)s'}) 59 ret = data.extract_info(URL,download=True) 60 except Exception as e: 61 self.pld.Destroy() 62 wx.MessageBox(str(e),"エラー",wx.ICON_ERROR) 63 self.timer.Stop() 64 return "Finish" 65 self.pld.Destroy() 66 self.timer.Stop() 67 return "Finish" 68 print (doit()) 69 def OnButton(self,event=None): 70 self.pld = wx.ProgressDialog("ダウンロード中です。","ダウンロード中です。\nしばらくお待ちください。") 71 self.dld() 72 def OnTimer(self,event=None): 73 try: 74 genzai = os.path.getsize(self.move_title+".mp4.part") 75 self.pld.SetRange(int(ceil(self.move_size))) 76 self.pld.Update("ダウンロード中です。","ダウンロード中です。\nしばらくお待ちください。",genzai) 77 except Exception as e: 78 self.pld.Pulse() 79 print(str(e)) 80 81app = wx.App(False) 82frame = MyFrame() 83frame.Show(True) 84app.MainLoop()
##環境
Windows10
64bit
Python3.9
あなたの回答
tips
プレビュー