imagepython-2.7bitmapwxpythonboxsizer

images in layers with movement and transparency - wxpython


It might sound unproper 'images in layers' like in Photoshop but in fact that is what I have and would like to make working.

I use a set of wx.boxsizer's to have a nice&organized screen after launching my program.

In one row of Horizontal wx.BoxSizer's I have 3 columns done with different wx.Panels and each of that is containing moving wx.StaticBitmaps done by a Timer function.

The second wx.Panel which is in the middle with 0 proportion to mantain original panel size contains 2 images actually, one PNG with transparency and the moving wx.StaticBitmap which should be the background for this PNG.

This is not working out for me. I simply want that the PNG to be over the other image which is moved by the timer. 2 layers if you like.

It is creating a nice very simple and basic action effect (like the object in the PNG is running)

Now I thought of a few ways to go about this but none of them worked:

  1. Figure out how python decides which image to bring in front and which would stay behind. Manipulate that
  2. Keep the moving image in the sizer and take out the PNG and place it over the moving image (than I need to dynamically determine where is that moving image)
  3. Make the moving image the wx.panel background and then probably I can simply call the transparent PNG over it.

I will paste here a part of my script for the brave eyes:

class AnimationPanel(wx.Panel):
  def __init__(self, parent):
    wx.Panel.__init__(self, parent)
    self.loc = wx.Image("intro/runner.png",wx.BITMAP_TYPE_PNG).ConvertToBitmap()
    self.locpic = wx.StaticBitmap(self, -1, self.loc, (0, 0), (self.loc.GetWidth(), self.loc.GetHeight()))
    self.xer = 3080
    self.xer2 = 2310
    self.xer3 = 1540
    self.env = wx.Image("intro/environ1.png",wx.BITMAP_TYPE_PNG).ConvertToBitmap()
    self.env2 = wx.Image("intro/environ2.png",wx.BITMAP_TYPE_PNG).ConvertToBitmap()
    self.env3 = wx.Image("intro/environ3.png",wx.BITMAP_TYPE_PNG).ConvertToBitmap()
    self.picture = wx.StaticBitmap(self, -1, self.env, (0, 0), (self.env.GetWidth(), self.env.GetHeight()))
    self.picture2 = wx.StaticBitmap(self, -1, self.env2, (770, 0), (self.env2.GetWidth(), self.env2.GetHeight()))
    self.picture3 = wx.StaticBitmap(self, -1, self.env3, (1540, 0), (self.env3.GetWidth(), self.env3.GetHeight()))
    self.timer = wx.Timer(self)            
    self.Bind(wx.EVT_TIMER, self.OnTimer, self.timer)
    self.timer.Start(5)

  def OnTimer(self, event):
    if self.xer <= 3080:
        self.xer += 1
        self.picture.Move((self.xer,0))
    else:
        self.xer = -770
    if self.xer2 <= 3080:
        self.xer2 += 1
        self.picture2.Move((self.xer2,0))
    else:
        self.xer2 = -770
    if self.xer3 <= 3080:
        self.xer3 += 1
        self.picture3.Move((self.xer3,0))
    else:
        self.xer3 = -770

This is in the main frame:

    ap = AnimationPanel(self)
    v2box = wx.BoxSizer(wx.HORIZONTAL)
    v2box.Add(someother, 1, wx.EXPAND)
    v2box.Add(ap, 0, wx.EXPAND)
    v2box.Add(someother, 1, wx.EXPAND)

I did put research in this but I'm quite of a beginner so please help me out with some simple tips or suggestions if it's possible.

Thanks.


Solution

  • In the wxpython demo install there is a samples folder that has a pySketch demo.

    In this code it creates dc drawn objects that can be moved in front and behind other objects.

    A quick look over this code it looks like the drawn items are stored in a list and then drawn in the list order.

    I guess that's how you would implement your layering, you would have a list of layers and in each layer you would store your items for that layer.