前提・実現したいこと
以前の質問wxpythonで透過gifと背景gifを同時に重ねて再生表示する方法と似ている質問になります。以下のgif動画の一番下にある箇所をなくし、ウィンドウそのものを透過させたいです。
開発環境
win10
python3.7
wxpython
発生している問題・エラーメッセージ
挑戦した方法はselfをSetTransparent効果にさせて透明化する方法です。
問題としては上の桜吹雪index.gifも透明になってしまい、全体的に透明化してしまいました。
該当のソースコード
python
1import wx 2import wx.adv 3 4 5def callLaterTimedGen(gen, done=None, stop=None): 6 def next_gen(): 7 interval = next(gen, stop) 8 if interval is not stop: 9 wx.CallLater(interval, next_gen) 10 wx.CallAfter(next_gen) 11 return gen 12 13 14class MyFrame(wx.Frame): 15 def __init__(self, parent=None, *args, **kw): 16 super().__init__(parent, *args, **kw) 17 18 self.menubar = wx.MenuBar(wx.MB_DOCKABLE) 19 self.filem = wx.Menu() 20 self.filem.Append(wx.ID_EXIT, '&Transparency') 21 22 self.menubar.Append(self.filem, '&File') 23 self.SetMenuBar(self.menubar) 24 self.Bind(wx.EVT_MENU, self.OnTrans) 25 26 self.bmp1 = None 27 self.bmp2 = None 28 self.Bind(wx.EVT_PAINT, self.OnPaint) 29 self.Bind(wx.EVT_TIMER, lambda _: self.Refresh()) 30 31 self.timer = wx.Timer(self) 32 self.timer.Start(200) 33 34 # panel = wx.Panel(self) 35 36 # self.gen1 = callLaterTimedGen(gifAnimation("unnamed.gif", self.SetBitmap1)) 37 self.gen2 = callLaterTimedGen(gifAnimation("index.gif", self.SetBitmap2, useMask=(0, 0, 0))) 38 39 #ボタンの作成 40 self.Button1=wx.Button(self, label="exit",pos=(20,100)) 41 self.Button2=wx.Button(self, label="print",pos=(20,150)) 42 43 #ボタンを割り当て 44 self.Bind(wx.EVT_BUTTON, self.close, self.Button1) 45 self.Bind(wx.EVT_BUTTON, self.printer, self.Button2) 46 47 self.Show(True) 48 49 self.transp = False 50 wx.CallLater(250, self.OnTrans, None) 51 52 def OnTrans(self, event): 53 if self.transp == False: 54 self.SetTransparent(30) 55 self.transp = True 56 else: 57 self.SetTransparent(255) 58 self.transp = False 59 60 def close(self,event): 61 self.Close(True) 62 63 def printer(self, event): 64 print("Button2") 65 self.gen1.close() 66 self.gen1 = callLaterTimedGen(gifAnimation("someiyoshino2.gif", self.SetBitmap1)) 67 68 def SetBitmap1(self, bmp): 69 self.bmp1 = bmp 70 71 def SetBitmap2(self, bmp): 72 self.bmp2 = bmp 73 74 def OnPaint(self, event): 75 dc = wx.PaintDC(self) 76 if self.bmp1: 77 # 背景 (mask: False) 78 dc.DrawBitmap(self.bmp1, 0, 0, False) 79 if self.bmp2: 80 # 透過 (mask: True) 81 dc.DrawBitmap(self.bmp2, 0, 0, True) 82 83 84def gifAnimation(filepath, setBitmap, useMask=None): 85 anim = wx.adv.Animation(filepath) 86 # self.transp = False 87 from itertools import cycle 88 for idx in cycle(range(anim.GetFrameCount())): 89 print('idx', idx) 90 delay = anim.GetDelay(idx)/10 91 print('delay', delay) 92 frame = anim.GetFrame(idx) 93 print('frame', frame) 94 if useMask: 95 frame.SetMaskColour(*useMask) 96 yield delay 97 setBitmap(frame.ConvertToBitmap()) 98 99 100def main(): 101 app = wx.App() 102 win = MyFrame(None, wx.ID_ANY, "ウィンドウ透過GIF重ね合わせテスト", size = (600,400)) 103 win.Centre() 104 win.Show() 105 106 app.MainLoop() 107 108 109if __name__ == '__main__': 110 main()
共有ファイル
夜桜index.gifの配置場所(google drive)
試したこと
この問題に対して以下のサイトなどを参照しました。
wxPython - 透明/アルファの背景を描画する(カスタムウィジェット/パネル用)
⇒目的のものと違っているようでした。
wxpythonはパネル上に矩形を描画しません
⇒以下のような確かにウィンドウを透明化した上に描画していますが、gif動画となるとPaintというわけにはいかないため、表示できませんでした。
コードは以下です。
python
1import wx 2from PIL import Image, ImageDraw 3import wx.adv 4def callLaterTimedGen(gen, done=None, stop=None): 5 def next_gen(): 6 interval = next(gen, stop) 7 if interval is not stop: 8 wx.CallLater(interval, next_gen) 9 wx.CallAfter(next_gen) 10 return gen 11 12class Frame(wx.Frame): 13 def __init__(self): 14 15 super(Frame, self).__init__(None) 16 self.Bind(wx.EVT_ERASE_BACKGROUND, self.OnEraseBackground) 17 self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown) 18 self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown) 19 self.Bind(wx.EVT_PAINT, self.OnPaint) 20 def OnEraseBackground(self, event): 21 pass # do nothing 22 def OnLeftDown(self, event): 23 print(event.GetPosition()) 24 def OnKeyDown(self, event): 25 if event.GetKeyCode() == wx.WXK_ESCAPE: 26 self.Close() 27 else: 28 event.Skip() 29 30 def SetBitmap2(self, bmp): 31 self.bmp2 = bmp 32 def OnPaint(self, event): 33 dc = wx.PaintDC(self) 34 dc.SetPen(wx.Pen('#d4d4d4')) 35 dc.SetBrush(wx.Brush('#c56c00')) 36 dc.DrawRectangle(10, 15, 90, 60) 37 print("Button2") 38 self.gen2 = callLaterTimedGen(gifAnimation("someiyoshino2.gif", self.SetBitmap2, useMask=(0, 0, 0))) 39 40 self.Show(True) 41 def printer(self, event): 42 print("Button2") 43 self.gen1.close() 44 self.gen1 = callLaterTimedGen(gifAnimation("someiyoshino2.gif", self.SetBitmap1)) 45 46def gifAnimation(filepath, setBitmap, useMask=None): 47 anim = wx.adv.Animation(filepath) 48 49 from itertools import cycle 50 for idx in cycle(range(anim.GetFrameCount())): 51 print('idx', idx) 52 delay = anim.GetDelay(idx)/10 53 print('delay', delay) 54 frame = anim.GetFrame(idx) 55 print('frame', frame) 56 if useMask: 57 frame.SetMaskColour(*useMask) 58 yield delay 59 setBitmap(frame.ConvertToBitmap()) 60 61if __name__ == '__main__': 62 app = wx.PySimpleApp() 63 frame = Frame() 64 frame.ShowFullScreen(True) 65 app.MainLoop()
selfごと透過しても目的は達成できなく、paintDCを使っても描画のみでgifを表示することができませんでした。
いっそのこと枠全体を.コンマでキャプチャして枠へ表示するという複雑な作りも考えましたができませんでした。2つのレイヤーを持たせるなどの方法もあるのでしょうか。
知見ある方アドバイス頂けないでしょうか。よろしくお願い致します。