Search code examples
wxpython

set picture as background


I want to draw one background picture and some smaller pictures on top of that (in foreground). As I understand, the picture which is painted at first get's the foreground and if I draw a second picture at the same position then it will be in the background. My problem is, that the background-picture must be drawn at the beginning and later (at a certain event) the foreground picture shall be drawn on top of that background picture. My bad solution: destroy the first (background-)picture and redraw it. problem: the picture is flickering. So is there any better solution? here is some code:

def drawBG(self):    
    self.picBG = wx.StaticBitmap(self,size=(1020,252),pos=(0,160))
    self.picBG.SetBitmap(wx.Bitmap(path))

def drawFG(self,event):
    self.picFG = wx.StaticBitmap(self,size=(80,80),pos=(500,180))
    self.picFG.SetBitmap(wx.Bitmap(path))
    self.picBG.Destroy()
    self.drawBG()

Solution

  • You could set the background image on your panel and then use wx.StaticBitmap widgets to put the other images on top of it. I wrote a tutorial on how to put a background picture on a wx.Panel: http://www.blog.pythonlibrary.org/2010/03/18/wxpython-putting-a-background-image-on-a-panel/

    Here's the code from my tutorial:

    import wx
    
    ########################################################################
    class MainPanel(wx.Panel):
        """"""
    
        #----------------------------------------------------------------------
        def __init__(self, parent):
            """Constructor"""
            wx.Panel.__init__(self, parent=parent)
            self.SetBackgroundStyle(wx.BG_STYLE_CUSTOM)
            self.frame = parent
    
            sizer = wx.BoxSizer(wx.VERTICAL)
            hSizer = wx.BoxSizer(wx.HORIZONTAL)
    
            for num in range(4):
                label = "Button %s" % num
                btn = wx.Button(self, label=label)
                sizer.Add(btn, 0, wx.ALL, 5)
            hSizer.Add((1,1), 1, wx.EXPAND)
            hSizer.Add(sizer, 0, wx.TOP, 100)
            hSizer.Add((1,1), 0, wx.ALL, 75)
            self.SetSizer(hSizer)
            self.Bind(wx.EVT_ERASE_BACKGROUND, self.OnEraseBackground)
    
        #----------------------------------------------------------------------
        def OnEraseBackground(self, evt):
            """
            Add a picture to the background
            """
            # yanked from ColourDB.py
            dc = evt.GetDC()
    
            if not dc:
                dc = wx.ClientDC(self)
                rect = self.GetUpdateRegion().GetBox()
                dc.SetClippingRect(rect)
            dc.Clear()
            bmp = wx.Bitmap("butterfly.jpg")
            dc.DrawBitmap(bmp, 0, 0)
    
    
    ########################################################################
    class MainFrame(wx.Frame):
        """"""
    
        #----------------------------------------------------------------------
        def __init__(self):
            """Constructor"""
            wx.Frame.__init__(self, None, size=(600,450))
            panel = MainPanel(self)        
            self.Center()
    
    ########################################################################
    class Main(wx.App):
        """"""
    
        #----------------------------------------------------------------------
        def __init__(self, redirect=False, filename=None):
            """Constructor"""
            wx.App.__init__(self, redirect, filename)
            dlg = MainFrame()
            dlg.Show()
    
    #----------------------------------------------------------------------
    if __name__ == "__main__":
        app = Main()
        app.MainLoop()
    

    Now you just have to swap the buttons out for StaticBitmap widgets.