python-3.xwxpythontransparencyshaped-window

How to use wxshaped window and png with transparency in Python 3?


Edit: Found out how to place a transparent wxPanel on my shaped frame, but now ı try to put a wxGridBagSizer on the wxPanel with some widgets in it but only the first widget will appear...Any ideas?

Original question :

Well I'm trying to make a wx.ShapedWindow with a png background that has transparency, the problem is that it looks like they changed the wx lib so to set the shape on the bitmap before we could use wx.RegionFromBitmap() but this is not working anymore, i tried to use wx.Region only but i can't figure out how to have the transparency ! I have a grey zone where i would like transparent region....

If anyone can help me !

Here's what i get now :

import wx
from os import getcwd

class ShapedFrame(wx.Frame):
    def __init__(self, parent, id, title):
        wx.Frame.__init__(self, None, -1, "Shaped Window", style = wx.FRAME_SHAPED | wx.SIMPLE_BORDER )
        self.hasShape = False
        self.delta = wx.Point(0,0)
        ImgDir = (getcwd()+u"\\img\\ex.png")
        self.bmp = wx.Image(ImgDir, wx.BITMAP_TYPE_ANY).ConvertToBitmap()
        w,h = self.bmp.GetWidth(), self.bmp.GetHeight()
        self.SetClientSize(w,h)
        #self.panel = wx.Panel(self, -1,size=(100,100))
        panel = Panel(self)
        panel.Show()
        dc = wx.ClientDC(self)
        dc.DrawBitmap(self.bmp, 0,0, True)
        self.SetWindowShape()
        self.Bind(wx.EVT_LEFT_DCLICK, self.OnDoubleClick)
        self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown)
        self.Bind(wx.EVT_LEFT_UP, self.OnLeftUp)
        self.Bind(wx.EVT_MOTION, self.OnMouseMove)
        self.Bind(wx.EVT_RIGHT_UP, self.OnExit)
        self.Bind(wx.EVT_PAINT, self.OnPaint)
        self.Bind(wx.EVT_WINDOW_CREATE, self.SetWindowShape)

################# EDIT ONLY BUTTON 0 WILL APPEAR ########################
        button0 = wx.Button(panel, -1, "hello 0")
        button1 = wx.Button(panel, -1, "hello 1")
        button2 = wx.Button(panel, -1, "hello 2")
        button3 = wx.Button(panel, -1, "hello 3")

        gbox7 = wx.GridBagSizer(0,0)
        gbox7.SetEmptyCellSize((10,10))
        gbox7.Add(button0,(0,0))
        gbox7.Add(button1,(0,1))
        gbox7.Add(button2,(1,0))
        gbox7.Add(button3,(1,1))

        panel.SetSizer(gbox7)

#######################################################################
    
    def SetWindowShape(self, evt=None):
        r = wx.Region(self.bmp,wx.TransparentColour)
        self.hasShape = self.SetShape(r)

    def OnDoubleClick(self, evt):
        if self.hasShape:
            self.SetShape(wx.Region())
            self.hasShape = False
        else:
            self.SetWindowShape()

    def OnPaint(self, evt):
        dc = wx.PaintDC(self)
        dc.DrawBitmap(self.bmp, 0,0, True)

    def OnExit(self, evt):
        self.Close()

    def OnLeftDown(self, evt):
        self.CaptureMouse()
        pos = self.ClientToScreen(evt.GetPosition())
        origin = self.GetPosition()
        self.delta = wx.Point(pos.x - origin.x, pos.y - origin.y)

    def OnMouseMove(self, evt):
        if evt.Dragging() and evt.LeftIsDown():
            pos = self.ClientToScreen(evt.GetPosition())
            newPos = (pos.x - self.delta.x, pos.y - self.delta.y)
            self.Move(newPos)

    def OnLeftUp(self, evt):
        if self.HasCapture():
            self.ReleaseMouse()

class Panel(wx.Panel):
    def __init__(self, parent):
        wx.Panel.__init__(self, parent, -1, size=(200, 200,),style=wx.TRANSPARENT_WINDOW)
        self.CenterOnParent()


app = wx.App()

ShapedFrame(None,-1,None).Show()

app.MainLoop()

Solution

  • Okay i found out a solution, looking in wx.coulor since 2.9 they added wxTransparentColour

    so i replaced :

    r = wx.Region(self.bmp,"grey",30)
    

    with:

    r = wx.Region(self.bmp,wx.TransparentColour)
    

    and it works fine ! Hope it will help other people too :)