Hi all. I am a new user of wxPython, and this is my first post to the
wxPython-users group.
I am building an application that has multiple animations with index
transparencies (not alpha) overlap contained within a ScrolledWindow.
I came up with two methods that work, one for Linux (Ubuntu 9.10) and
one for Windows (XP). But neither method works for both. The examples
require an animated GIF file with at least two frames called
"animation.gif".
I chose to use wxPython because it supposedly would allow me to write
code only once that is portable for multiple OSs.
First, I tried the simple approach:
#!/usr/bin/env python
import wxversion
wxversion.select("2.8")
import wx
import wx.animate
class MyPanel(wx.Panel):
def __init__(self, parent, id):
wx.Panel.__init__(self, parent, id)
ag_fname = "animation.gif"
ag = wx.animate.GIFAnimationCtrl(self, id, ag_fname, pos=(10,
10))
ag2 = wx.animate.GIFAnimationCtrl(self, id, ag_fname, pos=(40,
12))
ag.Play()
ag2.Play()
app = wx.PySimpleApp()
frame = wx.Frame(None, -1, "wx.animate.GIFAnimationCtrl()", size =
(500, 400))
MyPanel(frame, -1)
frame.Show(True)
app.MainLoop()
I placed the coordinates of the animations close to one another, and
they overlap.
In Windows XP, this does not work, because each animation clears its
background with the Panel background (grey by default), and this
produces a strobing effect, where the two animations take turns
showing themselves on top of the other.
In Linux however the two animations display perfectly overlapped.
So I dug around on the wiki, and found the example
http://wiki.wxpython.org/index.cgi/DoubleBufferedDrawing . I
simplified the example and integrated it with a ScrolledWindow. I set
a timer to update the animations 10 times a second. Here is the class:
class animation_buffered_scrolled_canvas(wx.ScrolledWindow):
def __init__(self, parent, id = wx.ID_ANY, size = wx.DefaultSize):
wx.ScrolledWindow.__init__(self, parent, id, (0, 0),
size=size, style=wx.SUNKEN_BORDER)
self.width = 600
self.height = 600
self.x = 0
self.y = 0
self.SetBackgroundColour("WHITE")
myAnimation = wx.animate.Animation("animation.gif")
frame0 = myAnimation.GetFrame(0)
self.bframe0 = frame0.ConvertToBitmap()
frame1 = myAnimation.GetFrame(1)
self.bframe1 = frame1.ConvertToBitmap()
self.bframec = self.bframe0
self.SetVirtualSize((self.width, self.height))
self.SetScrollRate(10,10)
self.idTIMER = wx.NewId() # pick a number
self.timer = wx.Timer(self, self.idTIMER) # message will be
sent to the panel
self.timer.Start(100, oneShot = False) # x100 milliseconds
self.Bind(wx.EVT_TIMER, self.on_timer, id = self.idTIMER) #
call the on_timer function
self.time_switch = False
wx.EVT_PAINT(self, self.OnPaint)
wx.EVT_SIZE(self, self.OnSize)
wx.EVT_SCROLLWIN(self, self.OnScroll)
self.OnSize(None)
def on_timer(self, event):
if (self.time_switch == False):
self.time_switch = True
self.bframec = self.bframe0
else:
self.time_switch = False
self.bframec = self.bframe1
self.UpdateDrawing()
def UpdateDrawing(self):
dc = wx.BufferedDC(wx.ClientDC(self), self._Buffer)
# self.PrepareDC(dc)
self.Draw(dc)
def OnPaint(self, event):
dc = wx.BufferedPaintDC(self, self._Buffer)
def OnSize(self,event):
Size = (self.width, self.height)
self._Buffer = wx.EmptyBitmap(*Size)
self.UpdateDrawing()
def OnScroll(self,event):
Size = (self.width, self.height)
self._Buffer = wx.EmptyBitmap(*Size)
self.UpdateDrawing()
event.Skip()
def Draw(self, dc):
dc.SetBackground(wx.Brush("White"))
dc.Clear()
x1, y1 = self.CalcScrolledPosition(0, 0)
x2, y2 = self.CalcScrolledPosition(10, 10)
x3, y3 = self.CalcScrolledPosition(200, 200)
x4, y4 = self.CalcScrolledPosition(203, 194)
dc.DrawBitmap(self.bframe1, x1, y1, True)
dc.DrawBitmap(self.bframec, x2, y2, True)
dc.DrawBitmap(self.bframec, x3, y3, True)
dc.DrawBitmap(self.bframe0, x4, y4, True)
This second method works perfectly on Windows, but on Linux no images
are displayed at all. I think GTK2 might have a problem drawing
bitmaps to a DC canvas. I am not sure.
I would appreciate any help fixing either of these two above examples
so that I can write code once and it will be compatible for both
platforms.
I will also need to draw colored primitive shapes and text on top of
these overlapping animations, so I am thinking that the double
buffered solution is better because I can do these operations
relatively easily with DC canvases.
Would anyone suggest I use Chris Barker's FloatCanvas? I heard that it
doesn't work properly with scrolling windows.
On a side note, how would I use the built-in buffering function
"SetDoubleBuffered(True)"? Can anyone provide an example of this, or
am I better off using the custom buffering system above?
Thanks for reading my post, and super-thanks for responding if you do
so.
-Deus