I have an interface showing some images that are computed on the fly, e.g. when the user resize the window. The computations are not quick, i.e. each takes a fraction of second. Because of that, their is some significant flickering when the window is resized.
I am providing an example below. The time.sleep() simulates the computation time required to generate the images.
I am looking for a way to avoid this flicker. Meaning, the content would refresh at once, when all computations are done. Interestingly, this is exactly what happens when images are not involved: if I keep the time.sleep() in the example below but remove relevant lines, the entire content of the window is updated at once, no matter the differences in computatino time of the subframes.
To be more precise, if I comment out the bitmap drawing part only (“dc.DrawBitmap(bitmap, 0, 0)”), the flickering still occurs. The flickering remains till I remove the call to image.ConvertToBitmap(). I do not know why.
Anyway, any help would be appreciated.
I am running wxpython 2.8.9.1 (gtk2-unicode) on Ubuntu 9.04.
Paul
···
–
print sys.version
2.6.2 (release26-maint, Apr 19 2009, 01:56:41)
[GCC 4.3.3]
print wx.version()
2.8.9.1 (gtk2-unicode)
–
import Image
import random
import time
import wx
def pilToImage(pil):
image = wx.EmptyImage(pil.size[0], pil.size[1])
image.SetData(pil.convert(‘RGB’).tostring())
return image
def imageToBitmap(image):
return image.ConvertToBitmap()
def pilToBitmap(pil):
return imageToBitmap(pilToImage(pil))
class Item(wx.Panel):
“”“Displays an image that is computed on the fly”“”
def init(self, parent):
wx.Panel.init(self, parent, style=wx.SIMPLE_BORDER | wx.FULL_REPAINT_ON_RESIZE)
self.Bind(wx.EVT_PAINT, self.OnPaint)
def OnPaint(self, event):
dc = wx.PaintDC(self)
dc.BeginDrawing()
# the following accounts for computation time
time.sleep(0.1 + 0.1 * random.random())
image = Image.new('F', dc.GetSizeTuple())
# remove the following two lines, and the flicker disappears
bitmap = pilToBitmap(image)
dc.DrawBitmap(bitmap, 0, 0)
dc.EndDrawing()
class MyFrame(wx.Frame):
“”“A display of three Item objects”“”
def init(self, *args, **kwargs):
wx.Frame.__init__(self, *args, **kwargs)
self.view = [Item(self),Item(self),Item(self)];
self.view[0].SetBackgroundColour(wx.Colour(100,0,0))
self.view[1].SetBackgroundColour(wx.Colour(0,100,0))
self.view[2].SetBackgroundColour(wx.Colour(0,0,100))
sizerVer = wx.BoxSizer(wx.VERTICAL)
sizerVer.Add(self.view[2], proportion = 1, flag = wx.EXPAND | wx.BOTTOM, border = 5)
sizerVer.Add(self.view[1], proportion = 1, flag = wx.EXPAND , border = 5)
sizerHor = wx.BoxSizer(wx.HORIZONTAL)
sizerHor.Add(self.view[0], proportion = 1, flag = wx.EXPAND | wx.ALL, border = 5)
sizerHor.Add(sizerVer, proportion = 1, flag = wx.EXPAND | wx.TOP | wx.BOTTOM | wx.RIGHT, border = 5)
self.SetSizer(sizerHor)
myApp = wx.App(0)
frame = MyFrame(None, wx.ID_ANY, “Main Frame”)
frame.Show()
myApp.MainLoop()